diff --git a/Makefile.m68k b/Makefile.m68k index 794f346..a32eecc 100644 --- a/Makefile.m68k +++ b/Makefile.m68k @@ -1,4 +1,4 @@ -all: zic zdump datepatch timezone lib +all: zic zdump datepatch timezone timezoneinfo lib CC = m68k-amigaos-gcc CFLAGS = -O2 -noixemul -DTZDIR=\"LOCALE:zoneinfo\" -DHAVE_ADJTIME=0 -DHAVE_DOS_FILE_NAMES -DHAVE_LINK=0 -DHAVE_SYMLINK=0 -DHAVE_SYS_STAT_H=0 -DTM_GMTOFF=tm_gmtoff -DTM_ZONE=tm_zone -Dtime_tz=long -DTLOCALTIME_IMPLEMENTATION -DALL_STATE -Wall #-Werror @@ -23,6 +23,8 @@ private.h: amiga_tz.h: touch amiga_tz.h +amiga_tz.o: amiga_tz.c private.h amiga_tz.h + asctime.o: asctime.c private.h tzfile.h date.o: date.c private.h @@ -39,34 +41,39 @@ zic.o: zic.c private.h tzfile.h version.h strtoll.o: strtoll.c amiga_tz.h -date_amiga.o: amiga_locale.c private.h amiga_tz.h +date_amiga.o: date_amiga.c private.h amiga_tz.h date.o: date.c private.h amiga_tz.h date_patch.o: date_patch.c private.h -timezone.o: timezone.c private.h +timezone.o: timezone.c amiga_tz.h zone.h + +timezoneinfo.o: timezoneinfo.c amiga_tz.h zic: zic.o ${CC} ${CFLAGS} -o zic zic.o $(LDFLAGS) $(LDLIBS) -zdump: zdump.o localtime.o asctime.o strtoll.c - ${CC} ${CFLAGS} -o zdump zdump.o localtime.o asctime.o strtoll.c $(LDFLAGS) $(LDLIBS) +zdump: zdump.o localtime.o asctime.o strtoll.o amiga_tz.o + ${CC} ${CFLAGS} -o zdump zdump.o localtime.o asctime.o strtoll.o amiga_tz.o $(LDFLAGS) $(LDLIBS) -date: date.o localtime.o strftime.o asctime.o strtoll.o amiga_locale.o - ${CC} ${CFLAGS} -o date date.o localtime.o strftime.o asctime.o strtoll.o date_amiga.o $(LDFLAGS) -lsocket $(LDLIBS) +date: date.o localtime.o strftime.o asctime.o strtoll.o date_amiga.o amiga_tz.o + ${CC} ${CFLAGS} -o datetz date.o localtime.o strftime.o asctime.o strtoll.o date_amiga.o amiga_tz.o $(LDFLAGS) -lsocket $(LDLIBS) lib: localtime.o asctime.o difftime.o strftime.o ${AR} rcs libtz.a localtime.o asctime.o difftime.o strftime.o -datepatch: date_patch.o localtime.o asctime.c - ${CC} ${CFLAGS} -o datepatch date_patch.o localtime.o asctime.c $(LDFLAGS) $(LDLIBS) +datepatch: date_patch.o localtime.o asctime.c amiga_tz.o + ${CC} ${CFLAGS} -o datepatch date_patch.o localtime.o asctime.c amiga_tz.o $(LDFLAGS) $(LDLIBS) -timezone: timezone.o - ${CC} ${CFLAGS} -o timezone timezone.o $(LDFLAGS) $(LDLIBS) +timezone: timezone.o localtime.o asctime.o amiga_tz.o + ${CC} ${CFLAGS} -o timezone timezone.o localtime.o asctime.o amiga_tz.o $(LDFLAGS) $(LDLIBS) + +timezoneinfo: timezoneinfo.o localtime.o asctime.o amiga_tz.o + ${CC} ${CFLAGS} -o timezoneinfo timezoneinfo.o localtime.o asctime.o amiga_tz.o $(LDFLAGS) $(LDLIBS) clean: - rm -f asctime.o date.o difftime.o localtime.o strftime.o zdump.o zic.o strtoll.o date_amiga.o version.h zic zdump date datepatch timezone libtz.a + rm -f amiga_tz.o asctime.o date.o difftime.o localtime.o strftime.o zdump.o zic.o strtoll.o date_amiga.o timezone.o timezoneinfo.o version.h zic zdump date datepatch timezone timezoneinfo libtz.a depend: @echo Dependencies already done diff --git a/amiga_tz.c b/amiga_tz.c new file mode 100644 index 0000000..ea2bd33 --- /dev/null +++ b/amiga_tz.c @@ -0,0 +1,291 @@ +/* + * Copyright (c) 2015 Carsten Larsen + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "private.h" +#include "amiga_tz.h" + +struct LocaleBase* ctypeBase = NULL; +struct Locale* ctypeLocale= NULL; +/**********************************************************************/ +void InitCTypeLocale() +{ + ctypeBase = (struct LocaleBase*)OpenLibrary("locale.library", 38L); + ctypeLocale = OpenLocale(NULL); +} + +void CleanupCTypeLocale() +{ + if (ctypeBase != NULL) { + CloseLocale(ctypeLocale); + ctypeLocale = NULL; + CloseLibrary((struct Library*)ctypeBase); + ctypeBase = NULL; + } +} +/**********************************************************************/ +int isalnum(int c) +{ + int res; + InitCTypeLocale(); + res = IsAlNum(ctypeLocale, (ULONG)c); + CleanupCTypeLocale(); + return res; +} + +int isalpha(int c) +{ + int res; + InitCTypeLocale(); + res = IsAlpha(ctypeLocale, (ULONG)c); + CleanupCTypeLocale(); + return res; +} + +int isdigit(int c) +{ + int res; + InitCTypeLocale(); + res = IsDigit(ctypeLocale, (ULONG)c); + CleanupCTypeLocale(); + return res; +} + +int ispunct(int c) +{ + int res; + InitCTypeLocale(); + res = IsPunct(ctypeLocale, (ULONG)c); + CleanupCTypeLocale(); + return res; +} + +int isspace(int c) +{ + int res; + InitCTypeLocale(); + res = IsSpace(ctypeLocale, (ULONG)c); + CleanupCTypeLocale(); + return res; +} + +int isupper(int c) +{ + int res; + InitCTypeLocale(); + res = IsUpper(ctypeLocale, (ULONG)c); + CleanupCTypeLocale(); + return res; +} + +int iscntrl(int c) +{ + int res; + InitCTypeLocale(); + res = IsCntrl(ctypeLocale, (ULONG)c); + CleanupCTypeLocale(); + return res; +} +/**********************************************************************/ +struct Device *TimerBase = NULL; +struct timerequest *request = NULL; + +int delete_timer() +{ + struct MsgPort *port; + if (request == NULL) + return 1; + + port = request->tr_node.io_Message.mn_ReplyPort; + + if (port != 0) + DeletePort(port); + + CloseDevice((struct IORequest*)request); + DeleteExtIO((struct IORequest*)request); + + return 0; +} + +int create_timer() +{ + LONG error; + struct MsgPort *port = CreatePort(0, 0); + if (port == NULL) + return 1; + + request = (struct timerequest*)CreateExtIO(port, sizeof(struct timerequest)); + if (request == NULL) + { + DeletePort(port); + return 1; + } + + error = OpenDevice(TIMERNAME, UNIT_MICROHZ, (struct IORequest*)request, 0L); + if (error != 0) + { + delete_timer(request); + return 1; + } + + TimerBase = (struct Device*)request->tr_node.io_Device; + + return 0; +} +/**********************************************************************/ +// The time () function returns the value of time in seconds since 0 hours, +// 0 minutes, 0 seconds, January 1, 1970, Coordinated Universal Time. If an +// error occurs, time () returns the value Po Vt time_t Pc Ns -1 . +// +// The return value is also stored in * tloc , provided that tloc is non-null. +// +tz_time_t time(tz_time_t *tloc) +{ + struct LocaleBase* localeBase; + struct Locale* locale; + struct timeval tv; + int error; + + localeBase = (struct LocaleBase*)OpenLibrary("locale.library", 38L); + if (localeBase == NULL) { + return 0; + } + + locale = OpenLocale(NULL); + if (locale == NULL) { + CloseLibrary((struct Library*)localeBase); + return 0; + } + + error = create_timer(); + if (error != 0) { + return 0; + } + + GetSysTime(&tv); + + if (tloc) { + *tloc = (time_t)tv.tv_secs - locale->loc_GMTOffset * 60; // Check for TZ GMT offset + } + + CloseLocale(locale); + CloseLibrary((struct Library*)localeBase); + delete_timer(); + + return (time_t)tv.tv_secs; //- locale->loc_GMTOffset * 60; // Check for TZ GMT offset +} + +int get_gmtoffset() +{ + struct tm tm; + timezone_t tz = NULL; + time_t now = time(NULL); + + char *ret = getenv("TZ"); + tz = tzalloc(ret); + + if (tz) { + localtime_rz(tz, &now, &tm); + tzfree(tz); + return tm.tm_gmtoff; + } + + return 0; +} +/**********************************************************************/ +int settimeofday(const struct timeval *tv, const struct timezone *tz) +{ + struct LocaleBase* localeBase; + struct Locale* locale; + int error; + + localeBase = (struct LocaleBase*)OpenLibrary("locale.library", 38L); + if (localeBase == NULL) { + return 1; + } + + locale = OpenLocale(NULL); + if (locale == NULL) { + CloseLibrary((struct Library*)localeBase); + return 1; + } + + error = create_timer(); + if (error != 0) { + return error; + } + + request->tr_node.io_Command = TR_SETSYSTIME; + request->tr_time.tv_secs = (long)tv->tv_secs - AMIGAOFFSET + locale->loc_GMTOffset * 60; + request->tr_time.tv_micro = tv->tv_micro; + DoIO((struct IORequest*)request); + + error = delete_timer(); + + CloseLocale(locale); + CloseLibrary((struct Library*)localeBase); + + return error; +} +/**********************************************************************/ +int settime(struct timeval *tv) +{ + int error = create_timer(); + if (error != 0) { + return error; + } + + request->tr_node.io_Command = TR_SETSYSTIME; + request->tr_time.tv_secs = (long)tv->tv_secs; + request->tr_time.tv_micro = tv->tv_micro; + DoIO((struct IORequest*)request); + + error = delete_timer(); + + return error; +} +/**********************************************************************/ +void underscore_add(char *string) +{ + char *s = string; + while (*s) { + if (*s == ' ') { + *s = '_'; + } + s++; + } +} + +void underscore_remove(char *string) +{ + char *s = string; + while (*s) { + if (*s == '_') { + *s = ' '; + } + s++; + } +} +/**********************************************************************/ diff --git a/amiga_tz.h b/amiga_tz.h index 192e1b0..d66343b 100644 --- a/amiga_tz.h +++ b/amiga_tz.h @@ -32,17 +32,46 @@ #include #include #include +#include +#include +#include #include #include +#include #include #include #include #include #include +#include +#include #include +#include + +// --------------------------------------------------------------------------- // + +#define OPEN_ERROR "Cannot open %s.\n" +#define OPEN_VER_ERROR "Cannot open %s v%s.\n" +#define REQ_ERROR "Requires Kickstart 2.04 (37.175) or later.\n" + +#define INTUILIB_NAME "intuition.library" +#define INTUILIB_REV 37L +#define GADTOOLLIB_NAME "gadtools.library" +#define GADTOOLLIB_REV 37L +#define UTILLIB_NAME "utility.library" +#define UTILLIB_REV 37L +#define LOCALELIB_NAME "locale.library" +#define LOCALELIB_REV 37L +#define DOSLIB_NAME "dos.library" +#define DOSLIB_REV 37L +#define TIMER_NAME TIMERNAME +#define BATTCLOCK_NAME BATTCLOCKNAME +#define PUBSCREEN_NAME "PubScreen" + +// --------------------------------------------------------------------------- // #ifndef ULONG -#define ULONG long unsigned int +#define ULONG long unsigned int #endif #ifndef LLONG_MAX @@ -58,6 +87,12 @@ #define AMIGAOFFSET 2922 * 24 * 60 * 60 #endif +#define ENVSIZE 100 + +int get_gmtoffset(); +void underscore_add(char *string); +void underscore_remove(char *string); + long long int strtoll(const char *nptr, char **endptr, int base); int isalnum(int c); diff --git a/date.c b/date.c index c04a67a..c8e660b 100644 --- a/date.c +++ b/date.c @@ -16,7 +16,6 @@ */ #include "private.h" -#include "date_amiga.h" #if HAVE_ADJTIME || HAVE_SETTIMEOFDAY #include "sys/time.h" /* for struct timeval, struct timezone */ #endif /* HAVE_ADJTIME || HAVE_SETTIMEOFDAY */ diff --git a/date_amiga.c b/date_amiga.c index 535ed1e..30ac2dc 100644 --- a/date_amiga.c +++ b/date_amiga.c @@ -25,8 +25,7 @@ */ #include "private.h" -#include "date_amiga.h" - +#include "amiga_tz.h" #include "version.h" const char *vers = "\0$VER: tzdate" AMIGA_VERSION; @@ -36,227 +35,3 @@ void syslog(int pri, const char *fmt, ...) { } void logwtmp(const char *line, const char *name, const char *host) { } void lose(int i) { } /**********************************************************************/ -struct LocaleBase* ctypeBase = NULL; -struct Locale* ctypeLocale= NULL; - -void InitCTypeLocale() -{ - ctypeBase = (struct LocaleBase*)OpenLibrary("locale.library", 38L); - ctypeLocale = OpenLocale(NULL); -} - -void CleanupCTypeLocale() -{ - if (ctypeBase != NULL) { - CloseLocale(ctypeLocale); - ctypeLocale = NULL; - CloseLibrary((struct Library*)ctypeBase); - ctypeBase = NULL; - } -} -/**********************************************************************/ -int isalnum(int c) -{ - int res; - InitCTypeLocale(); - res = IsAlNum(ctypeLocale, (ULONG)c); - CleanupCTypeLocale(); - return res; -} - -int isalpha(int c) -{ - int res; - InitCTypeLocale(); - res = IsAlpha(ctypeLocale, (ULONG)c); - CleanupCTypeLocale(); - return res; -} - -int isdigit(int c) -{ - int res; - InitCTypeLocale(); - res = IsDigit(ctypeLocale, (ULONG)c); - CleanupCTypeLocale(); - return res; -} - -int ispunct(int c) -{ - int res; - InitCTypeLocale(); - res = IsPunct(ctypeLocale, (ULONG)c); - CleanupCTypeLocale(); - return res; -} - -int isspace(int c) -{ - int res; - InitCTypeLocale(); - res = IsSpace(ctypeLocale, (ULONG)c); - CleanupCTypeLocale(); - return res; -} - -int isupper(int c) -{ - int res; - InitCTypeLocale(); - res = IsUpper(ctypeLocale, (ULONG)c); - CleanupCTypeLocale(); - return res; -} - -int iscntrl(int c) -{ - int res; - InitCTypeLocale(); - res = IsCntrl(ctypeLocale, (ULONG)c); - CleanupCTypeLocale(); - return res; -} -/**********************************************************************/ -struct Device *TimerBase = NULL; -struct timerequest *request = NULL; - -int delete_timer() -{ - struct MsgPort *port; - if (request == NULL) - return 1; - - port = request->tr_node.io_Message.mn_ReplyPort; - - if (port != 0) - DeletePort(port); - - CloseDevice((struct IORequest*)request); - DeleteExtIO((struct IORequest*)request); - - return 0; -} - -int create_timer() -{ - LONG error; - struct MsgPort *port = CreatePort(0, 0); - if (port == NULL) - return 1; - - request = (struct timerequest*)CreateExtIO(port, sizeof(struct timerequest)); - if (request == NULL) - { - DeletePort(port); - return 1; - } - - error = OpenDevice(TIMERNAME, UNIT_MICROHZ, (struct IORequest*)request, 0L); - if (error != 0) - { - delete_timer(request); - return 1; - } - - TimerBase = (struct Device*)request->tr_node.io_Device; - - return 0; -} -/**********************************************************************/ -// The time () function returns the value of time in seconds since 0 hours, -// 0 minutes, 0 seconds, January 1, 1970, Coordinated Universal Time. If an -// error occurs, time () returns the value Po Vt time_t Pc Ns -1 . -// -// The return value is also stored in * tloc , provided that tloc is non-null. -// -tz_time_t time(tz_time_t *tloc) -{ - struct LocaleBase* localeBase; - struct Locale* locale; - struct timeval tv; - int error; - - localeBase = (struct LocaleBase*)OpenLibrary("locale.library", 38L); - if (localeBase == NULL) { - return 0; - } - - locale = OpenLocale(NULL); - if (locale == NULL) { - CloseLibrary((struct Library*)localeBase); - return 0; - } - - error = create_timer(); - if (error != 0) { - return 0; - } - - GetSysTime(&tv); - - if (tloc) { - *tloc = (time_t)tv.tv_secs - locale->loc_GMTOffset * 60; // Check for TZ GMT offset - } - - CloseLocale(locale); - CloseLibrary((struct Library*)localeBase); - delete_timer(); - - return (time_t)tv.tv_secs; //- locale->loc_GMTOffset * 60; // Check for TZ GMT offset -} - -int get_gmtoffset() -{ - struct tm tm; - timezone_t tz = NULL; - time_t now = time(NULL); - - char *ret = getenv("TZ"); - tz = tzalloc(ret); - - if (tz) { - localtime_rz(tz, &now, &tm); - tzfree(tz); - return tm.tm_gmtoff; - } - - return 0; -} - -/**********************************************************************/ -int settimeofday(const struct timeval *tv, const struct timezone *tz) -{ - struct LocaleBase* localeBase; - struct Locale* locale; - int error; - - localeBase = (struct LocaleBase*)OpenLibrary("locale.library", 38L); - if (localeBase == NULL) { - return 1; - } - - locale = OpenLocale(NULL); - if (locale == NULL) { - CloseLibrary((struct Library*)localeBase); - return 1; - } - - error = create_timer(); - if (error != 0) { - return error; - } - - request->tr_node.io_Command = TR_SETSYSTIME; - request->tr_time.tv_secs = (long)tv->tv_secs - AMIGAOFFSET + locale->loc_GMTOffset * 60; - request->tr_time.tv_micro = tv->tv_micro; - DoIO((struct IORequest*)request); - - error = delete_timer(); - - CloseLocale(locale); - CloseLibrary((struct Library*)localeBase); - - return error; -} -/**********************************************************************/ diff --git a/date_patch.c b/date_patch.c index 6118d5d..6100743 100644 --- a/date_patch.c +++ b/date_patch.c @@ -24,49 +24,15 @@ * */ +#include "private.h" +#include "amiga_tz.h" #include "version.h" const char *vers = "\0$VER: datepatch" AMIGA_VERSION; -#include "private.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define OPEN_ERROR "Cannot open %s.\n" -#define OPEN_VER_ERROR "Cannot open %s v%s.\n" -#define REQ_ERROR "Requires Kickstart 2.04 (37.175) or later.\n" - -#define UTILLIB_NAME "utility.library" -#define UTILLIB_REV 37L -#define LOCALELIB_NAME "locale.library" -#define LOCALELIB_REV 37L -#define DOSLIB_NAME "dos.library" -#define DOSLIB_REV 37L -#define TIMER_NAME TIMERNAME -#define BATTCLOCK_NAME BATTCLOCKNAME - struct Library *BattClockBase; struct Library *DOSBase = NULL; struct Library *UtilityBase = NULL; struct Library *LocaleBase = NULL; -struct Device *TimerBase = NULL; -struct timerequest *request = NULL; - -int create_timer(); -int delete_timer(); void amiga_open_lib_error(char *name, int version) { @@ -97,21 +63,12 @@ int amiga_open_libs() printf(OPEN_ERROR, BATTCLOCK_NAME); return 1; } - - if (create_timer() != 0) { - printf(OPEN_ERROR, TIMER_NAME); - return 1; - } - + return 0; } void amiga_close_libs() { - if (request != NULL) { - delete_timer(); - } - if (LocaleBase != NULL) { CloseLibrary(LocaleBase); LocaleBase = NULL; @@ -128,77 +85,6 @@ void amiga_close_libs() } } -int create_timer() -{ - LONG error; - struct MsgPort *port = CreatePort(0, 0); - if (port == NULL) - return 1; - - request = (struct timerequest*)CreateExtIO(port, sizeof(struct timerequest)); - if (request == NULL) - { - DeletePort(port); - return 1; - } - - error = OpenDevice(TIMER_NAME, UNIT_MICROHZ, (struct IORequest*)request, 0L); - if (error != 0) - { - delete_timer(request); - return 1; - } - - TimerBase = (struct Device*)request->tr_node.io_Device; - - return 0; -} - -int delete_timer() -{ - struct MsgPort *port; - if (request == NULL) - return 1; - - port = request->tr_node.io_Message.mn_ReplyPort; - - if (port != 0) - DeletePort(port); - - CloseDevice((struct IORequest*)request); - DeleteExtIO((struct IORequest*)request); - - return 0; -} - -int get_gmtoffset() -{ - struct tm tm; - timezone_t tz = NULL; - time_t now = time(NULL); - - char *ret = getenv("TZ"); - tz = tzalloc(ret); - - if (tz) { - localtime_rz(tz, &now, &tm); - tzfree(tz); - return tm.tm_gmtoff; - } - - return 0; -} - -int settime(struct timeval *tv) -{ - request->tr_node.io_Command = TR_SETSYSTIME; - request->tr_time.tv_secs = (long)tv->tv_secs; - request->tr_time.tv_micro = tv->tv_micro; - DoIO((struct IORequest*)request); - - return 0; -} - void PatchedWriteBattClock(unsigned long time) { WriteBattClock(time - get_gmtoffset()); @@ -225,7 +111,7 @@ void amiga_patch_libs() Forbid(); SetFunction(BattClockBase,(long)&ReadBattClock,(unsigned long (*)())PatchedReadBattClock); SetFunction(BattClockBase,(long)&WriteBattClock,(unsigned long (*)())PatchedWriteBattClock); - //SetFunction(LocaleBase,(long)&OpenLocale,(unsigned long (*)())PatchedOpenLocale); + SetFunction(LocaleBase,(long)&OpenLocale,(unsigned long (*)())PatchedOpenLocale); Permit(); ((struct CommandLineInterface *)BADDR(((struct Process *)FindTask(NULL))->pr_CLI))->cli_Module=NULL; diff --git a/localtime.c b/localtime.c index d6c2eea..1c53576 100644 --- a/localtime.c +++ b/localtime.c @@ -2246,7 +2246,7 @@ posix2time(time_t t) /* Convert from the underlying system's time_t to the ersatz time_tz, which is called 'time_t' in this file. */ - +/* time_t time(time_t *p) { @@ -2255,5 +2255,5 @@ time(time_t *p) *p = r; return r; } - +*/ #endif diff --git a/timezone.c b/timezone.c index b1cc966..68e160f 100644 --- a/timezone.c +++ b/timezone.c @@ -24,20 +24,473 @@ * */ +/** + * @file tzselect.c + * @brief + * Inspired from example at: + * http://thomas-rapp.homepage.t-online.de/examples/lv.c + * + * Retrieved 2015-06-20 + * + */ + +// --------------------------------------------------------------------------- // +#include +#include +#include +#include "zone.h" +#include "amiga_tz.h" #include "version.h" const char *vers = "\0$VER: timezone" AMIGA_VERSION; +// --------------------------------------------------------------------------- // +#define GID_LIST 1001 +#define GID_STRING 1002 +#define GID_TZ 1003 +#define GID_SAVE 1010 +#define GID_USE 1011 +#define GID_CANCEL 1012 -#include +#ifndef __amigaos4__ +#define NewList(list) ((list)->lh_Head = (struct Node *)&(list)->lh_Tail,(list)->lh_TailPred = (struct Node *)&(list)->lh_Head,(list)->lh_Tail = NULL) +#define GetHead(list) ((list) && (list)->lh_Head && (list)->lh_Head->ln_Succ ? (list)->lh_Head : NULL) +#define GetTail(list) ((list) && (list)->lh_TailPred && (list)->lh_TailPred->ln_Pred ? (list)->lh_TailPred : NULL) +#define GetSucc(node) ((node) && (node)->ln_Succ->ln_Succ ? (node)->ln_Succ : NULL) +#define GetPred(node) ((node) && (node)->ln_Pred->ln_Pred ? (node)->ln_Pred : NULL) +#endif +// --------------------------------------------------------------------------- // +// Globals variables +char *tz = NULL; +struct Library *DOSBase = NULL; +struct Library *UtilityBase = NULL; +struct Library *IntuitionBase = NULL; +struct Library *GadToolsBase = NULL; +struct Screen *screen = NULL; +struct Window *window = NULL; +struct Gadget *glist = NULL; +int gmtoffset = 0; -int main(const int argc, char *argv[]) +// Window variables +struct Gadget *lvgad; +struct Gadget *strgad; +struct Gadget *tzgad; +struct List lvlist; +char *tztext = NULL; + +// Shared temporary variables +struct Gadget *lastgad; +int width; +int height; + +// --------------------------------------------------------------------------- // +void amiga_cleanup(); + +void amiga_open_lib_error(char *name, int version) { - char *ret = getenv("TZ"); + fprintf(stderr, OPEN_VER_ERROR, name, version); + fprintf(stderr, REQ_ERROR); +} - if (ret != NULL) { - printf("Timezone (tz) is %s", ret); - } else { - printf("Timezone variable not set.\n"); +int amiga_open_libs() +{ + atexit(amiga_cleanup); + + if(!(DOSBase = OpenLibrary(DOSLIB_NAME, DOSLIB_REV))) { + amiga_open_lib_error(DOSLIB_NAME, DOSLIB_REV); + return 1; } + if(!(UtilityBase = OpenLibrary(UTILLIB_NAME, UTILLIB_REV))) { + amiga_open_lib_error(UTILLIB_NAME, UTILLIB_REV); + return 1; + } + + if(!(IntuitionBase = OpenLibrary(INTUILIB_NAME, INTUILIB_REV))) { + amiga_open_lib_error(INTUILIB_NAME, INTUILIB_REV); + return 1; + } + + if(!(GadToolsBase = OpenLibrary(GADTOOLLIB_NAME, GADTOOLLIB_REV))) { + amiga_open_lib_error(GADTOOLLIB_NAME, GADTOOLLIB_REV); + return 1; + } + + if (!(screen = (struct Screen*)LockPubScreen(NULL))) + { + fprintf(stderr, OPEN_ERROR, PUBSCREEN_NAME); + return 1; + } + + if (!(lastgad = CreateContext(&glist))) + { + fprintf(stderr, "cannot create gadget objects\n"); + return 1; + } + + NewList(&lvlist); + return 0; } + +void amiga_cleanup() +{ + struct Node *node; + + if (window != NULL) { + CloseWindow(window); + window = NULL; + } + + while ((node = RemHead(&lvlist))) { + FreeVec(node); + } + + if (glist != NULL) { + FreeGadgets (glist); + glist = NULL; + } + + if (screen != NULL) { + UnlockPubScreen (NULL, screen); + screen = NULL; + } + + if (GadToolsBase != NULL) { + CloseLibrary(UtilityBase); + UtilityBase = NULL; + } + + if (IntuitionBase != NULL) { + CloseLibrary(UtilityBase); + UtilityBase = NULL; + } + + if (UtilityBase != NULL) { + CloseLibrary(UtilityBase); + UtilityBase = NULL; + } + + if (DOSBase != NULL) { + CloseLibrary(DOSBase); + DOSBase = NULL; + } + + if (tztext != NULL) { + FreeVec(tztext); + tztext = NULL; + } + + if (tz != NULL) { + FreeVec(tz); + tz = NULL; + } +} + +// --------------------------------------------------------------------------- // + +int amiga_open_window() +{ + window = (struct Window*)OpenWindowTags ( + NULL, + WA_Title, "Time zone preferences", + WA_Width, width, + WA_Height, height, + WA_Left, (screen->Width - width) / 2, + WA_Top, (screen->Height - height) / 2, + WA_Flags,WFLG_CLOSEGADGET | WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_ACTIVATE, + WA_IDCMP,IDCMP_CLOSEWINDOW | IDCMP_VANILLAKEY | IDCMP_REFRESHWINDOW | BUTTONIDCMP | STRINGIDCMP | LISTVIEWIDCMP, + WA_PubScreen, screen, + WA_Gadgets, glist, + TAG_END + ); + + return window != NULL ? 0 : 1; +} + +void amiga_setup_gui() +{ + struct NewGadget ng; + int fontw, fonth; + + ng.ng_VisualInfo = GetVisualInfo(screen, TAG_END); + ng.ng_TextAttr = screen->Font; + ng.ng_Flags = 0; + + fontw = screen->RastPort.TxWidth; + fonth = screen->RastPort.TxHeight; + + width = screen->WBorTop + fonth + 5; /* top of listview */ + height = 20 * fonth + 4; /* height of listview */ + + ng.ng_LeftEdge = screen->WBorLeft + 4; + ng.ng_TopEdge = width + height; + ng.ng_Height = fonth + 6; + ng.ng_Width = (3*16 * fontw + 3*8 + 2*4); + ng.ng_GadgetText = NULL; + ng.ng_GadgetID = GID_STRING; + lastgad = CreateGadget(STRING_KIND,lastgad,&ng,GA_Disabled,TRUE,TAG_END); + strgad = lastgad; + + ng.ng_TopEdge = width; + ng.ng_Height += height; /* including string height */ + ng.ng_GadgetID = GID_LIST; + lastgad = CreateGadget(LISTVIEW_KIND,lastgad,&ng,GTLV_Labels,&lvlist,GTLV_ShowSelected,lastgad,TAG_END); + lvgad = lastgad; + + ng.ng_TopEdge += ng.ng_Height + 4; + ng.ng_Width = 16 * fontw + 8; + ng.ng_Height = fonth + 6; + ng.ng_GadgetText = ""; + ng.ng_GadgetID = GID_TZ; + lastgad = CreateGadget(TEXT_KIND, lastgad, &ng, TAG_END); + tzgad = lastgad; + + /* + ng.ng_LeftEdge += ng.ng_Width + 4; + ng.ng_GadgetText = "Remove"; + ng.ng_GadgetID = GID_REMOVE; + gad = CreateGadget (BUTTON_KIND,gad,&ng,TAG_END); + + ng.ng_LeftEdge += ng.ng_Width + 4; + ng.ng_GadgetText = "Sort"; + ng.ng_GadgetID = GID_SORT; + gad = CreateGadget (BUTTON_KIND,gad,&ng,TAG_END); + */ + + ng.ng_TopEdge += (ng.ng_Height + 4) * 1.5; + ng.ng_LeftEdge = screen->WBorLeft + 4; + ng.ng_GadgetText = "Save"; + ng.ng_GadgetID = GID_SAVE; + lastgad = CreateGadget (BUTTON_KIND,lastgad,&ng,TAG_END); + + ng.ng_LeftEdge += ng.ng_Width + 4; + ng.ng_GadgetText = "Use"; + ng.ng_GadgetID = GID_USE; + lastgad = CreateGadget (BUTTON_KIND,lastgad,&ng,TAG_END); + + ng.ng_LeftEdge += ng.ng_Width + 4; + ng.ng_GadgetText = "Cancel"; + ng.ng_GadgetID = GID_CANCEL; + lastgad = CreateGadget (BUTTON_KIND,lastgad,&ng,TAG_END); + + width = ng.ng_LeftEdge + ng.ng_Width + 4 + screen->WBorRight; + height = ng.ng_TopEdge + ng.ng_Height + 4 + screen->WBorBottom; +} + +// --------------------------------------------------------------------------- // + +void load_tz() +{ + if (tz != NULL) { + FreeVec(tz); + tz = NULL; + } + + tz = AllocVec(ENVSIZE, MEMF_ANY | MEMF_CLEAR); + GetVar("TZ", tz, ENVSIZE - 1, GVF_GLOBAL_ONLY); + + underscore_remove(tz); + gmtoffset = get_gmtoffset(); +} + +void set_tz(char *newtz) +{ + if (tz != NULL) { + FreeVec(tz); + tz = NULL; + } + + tz = AllocVec(strlen(newtz) + 1, MEMF_ANY); + strcpy(tz, newtz); +} + +void use_tz() +{ + int offset; + + if (tz != NULL) { + underscore_add(tz); + SetVar("TZ", tz, strlen(tz), GVF_GLOBAL_ONLY); + } +} + +void save_tz() +{ + BPTR file; + if (tz != NULL) { + underscore_add(tz); + if ((file = Open("ENVARC:TZ", MODE_NEWFILE))) { + FPuts(file, tz); + Close(file); + } + } +} + +void show_tz() +{ + if (tztext != NULL) { + FreeVec(tztext); + } + + if (tz != NULL) { + const char *txt1 = "Timezone is set to "; + tztext = AllocVec(strlen(txt1) + strlen(tz) + 1, MEMF_ANY); + strcpy(tztext, txt1); + strcat(tztext, tz); + } else { + const char *deftz = "Timezone is not set"; + tztext = AllocVec(strlen(deftz) + 1, MEMF_ANY); + strcpy(tztext, deftz); + } + + GT_SetGadgetAttrs(tzgad, window, NULL, GTTX_Text, tztext, TAG_END); +} + +// --------------------------------------------------------------------------- // + +int cmploc (const void * a, const void * b) +{ + struct Location *loca, *locb; + loca = (struct Location*)a; + locb = (struct Location*)b; + return strcmp(loca->tz, locb->tz); +} + +void populate_list() +{ + unsigned int i; + struct Node *node = NULL; + const unsigned int count = sizeof(locations) / sizeof(struct Location); + + qsort(locations, count, sizeof(struct Location), cmploc); + + for (i = 0; i < count; i++) { + if ((node = AllocVec(sizeof(struct Node) + strlen(locations[i].tz) + 1, MEMF_CLEAR))) { + node->ln_Name = (STRPTR)(node + 1); + strcpy(node->ln_Name,locations[i].tz); + underscore_remove(node->ln_Name); + AddTail(&lvlist, node); + } + } +} + +// --------------------------------------------------------------------------- // + +struct Node *get_node (struct List *list,ULONG num) +{ + struct Node *node; + ULONG i = 0; + + for (node = GetHead(list); node; node = GetSucc(node)) + { + if (i == num) + return (node); + i ++; + } + + return (NULL); +} + +ULONG node_number (struct List *list,struct Node *node_to_find) +{ + struct Node *node; + ULONG i = 0; + + for (node = GetHead(list); node; node = GetSucc(node)) + { + if (node == node_to_find) + return (i); + i ++; + } + + return (-1); +} + +// --------------------------------------------------------------------------- // + +int main (void) +{ + BOOL cont; + ULONG num; + ULONG winsig, sigs; + struct Gadget *gad; + struct Node *node = NULL; + struct IntuiMessage *imsg; + + if (amiga_open_libs()) { + exit(5); + } + + amiga_setup_gui(); + load_tz(); + show_tz(); + populate_list(); + + if (amiga_open_window()) { + exit(5); + } + + GT_RefreshWindow(window, NULL); + GT_SetGadgetAttrs(lvgad, window, NULL, GTLV_Labels, &lvlist, TAG_END); + + winsig = 1L << window->UserPort->mp_SigBit; + cont = TRUE; + + do { + sigs = Wait(winsig | SIGBREAKF_CTRL_C); + + if (sigs & SIGBREAKF_CTRL_C) { + cont = FALSE; + } + + if (sigs & winsig) { + while ((imsg = GT_GetIMsg(window->UserPort))) { + switch (imsg->Class) { + case IDCMP_GADGETUP: + gad = (struct Gadget *)imsg->IAddress; + switch (gad->GadgetID) { + case GID_SAVE: + cont = FALSE; + save_tz(); + break; + case GID_USE: + cont = FALSE; + use_tz(); + break; + case GID_CANCEL: + cont = FALSE; + break; + case GID_LIST: + GT_GetGadgetAttrs(lvgad, window, NULL, GTLV_Selected, &num, TAG_END); + if ((node = get_node(&lvlist, num))) { + set_tz(node->ln_Name); + GT_SetGadgetAttrs (strgad, window, NULL, GTST_String, node->ln_Name, GA_Disabled, FALSE, TAG_END); + ActivateGadget(strgad, window, NULL); + } + break; + } + break; + case IDCMP_VANILLAKEY: + if (imsg->Code == 0x1b) /* Esc */ + cont = FALSE; + break; + case IDCMP_REFRESHWINDOW: + GT_BeginRefresh(window); + GT_EndRefresh(window, TRUE); + break; + case IDCMP_CLOSEWINDOW: + cont = FALSE; + break; + } + + GT_ReplyIMsg(imsg); + } + } + } + while (cont); + + amiga_cleanup(); + return 0; +} + + + diff --git a/timezoneinfo.c b/timezoneinfo.c new file mode 100644 index 0000000..6c22680 --- /dev/null +++ b/timezoneinfo.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2015 Carsten Larsen + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include "private.h" +#include "amiga_tz.h" +#include "version.h" +const char *vers = "\0$VER: timezone" AMIGA_VERSION; + +int main(const int argc, char *argv[]) +{ + struct tm tm; + timezone_t tz = NULL; + time_t now = time(NULL); + char *ret = getenv("TZ"); + tz = tzalloc(ret); + + if (ret != NULL) { + underscore_remove(ret); + printf("Location is %s\n", ret); + } else { + printf("Timezone variable not set.\n"); + } + + if (tz) { + localtime_rz(tz, &now, &tm); + tzfree(tz); + + printf("Timezone is %s\n", tm.tm_zone); + printf("GMT offset is %i hours\n", tm.tm_gmtoff / 60 / 60); + + if (tm.tm_isdst) { + printf("It is daylight saving time.\n"); + } else { + printf("It is not daylight saving time.\n"); + } + } else { + printf("Value of timezone is unknown.\n"); + } + + return 0; +} diff --git a/tzselect.c b/tzselect.c deleted file mode 100644 index 551117d..0000000 --- a/tzselect.c +++ /dev/null @@ -1,342 +0,0 @@ -/* - * Copyright (c) 2015 Carsten Larsen - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -/** - * @file tzselect.c - * @brief - * Inspired from example at: - * http://thomas-rapp.homepage.t-online.de/examples/lv.c - * - * Retrieved 2015-06-20 - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "zone.h" - -#define GID_LIST 1001 -#define GID_STRING 1002 -#define GID_SAVE 1010 -#define GID_USE 1011 -#define GID_CANCEL 1012 - -#ifndef __amigaos4__ -#define NewList(list) ((list)->lh_Head = (struct Node *)&(list)->lh_Tail,(list)->lh_TailPred = (struct Node *)&(list)->lh_Head,(list)->lh_Tail = NULL) -#define GetHead(list) ((list) && (list)->lh_Head && (list)->lh_Head->ln_Succ ? (list)->lh_Head : NULL) -#define GetTail(list) ((list) && (list)->lh_TailPred && (list)->lh_TailPred->ln_Pred ? (list)->lh_TailPred : NULL) -#define GetSucc(node) ((node) && (node)->ln_Succ->ln_Succ ? (node)->ln_Succ : NULL) -#define GetPred(node) ((node) && (node)->ln_Pred->ln_Pred ? (node)->ln_Pred : NULL) -#endif - -void free_list (struct List *list) - -{ - struct Node *node; - - while (node = RemHead (list)) - FreeVec (node); -} - -struct Node *get_node (struct List *list,ULONG num) - -{ - struct Node *node; - ULONG i = 0; - - for (node = GetHead(list); node; node = GetSucc(node)) - { - if (i == num) - return (node); - i ++; - } - - return (NULL); -} - -ULONG node_number (struct List *list,struct Node *node_to_find) - -{ - struct Node *node; - ULONG i = 0; - - for (node = GetHead(list); node; node = GetSucc(node)) - { - if (node == node_to_find) - return (i); - i ++; - } - - return (-1); -} -/*----------------------------------------------------------------------------*/ -/* Eine Node mit neuem Text ersetzen */ -/*----------------------------------------------------------------------------*/ - -struct Node *replace_node_text (struct List *list,struct Node *node,char *text) - -{ - struct Node *pred; - struct Node *new; - - if (new = AllocVec (sizeof(struct Node) + strlen(text) + 1,MEMF_CLEAR)) - { - new->ln_Name = (STRPTR)(new + 1); - strcpy (new->ln_Name,text); - - pred = node->ln_Pred; - - Remove (node); - FreeVec (node); - - Insert (list,new,pred); - } - - return (new); -} - -int cmploc (const void * a, const void * b) -{ - struct Location *loca, *locb; - loca = (struct Location*)a; - locb = (struct Location*)b; - return strcmp(loca->tz, locb->tz); -} - -/**********************************/ - -int main (void) -{ - struct Screen *screen; - struct Window *window; - struct NewGadget ng; - - struct Gadget *glist, *gad; - - int width, height; - int fontw, fonth; - struct List lvlist; - - ULONG winsig; - ULONG sigs; - BOOL cont; - struct Gadget *lvgad; - struct Gadget *strgad; - struct Node *node = NULL; - struct Node *nextnode; - struct IntuiMessage *imsg; - ULONG size; - char *text; - ULONG num; - - unsigned int i; - const unsigned int count = sizeof(locations) / sizeof(struct Location); - - NewList (&lvlist); - - if (!(screen = LockPubScreen(NULL))) - { - exit(10); - } - - glist = NULL; - gad = CreateContext(&glist); - - // ********************************************************** // - ng.ng_VisualInfo = GetVisualInfo(screen, TAG_END); - ng.ng_TextAttr = screen->Font; - ng.ng_Flags = 0; - - fontw = screen->RastPort.TxWidth; - fonth = screen->RastPort.TxHeight; - - width = screen->WBorTop + fonth + 5; /* top of listview */ - height = 20 * fonth + 4; /* height of listview */ - - ng.ng_LeftEdge = screen->WBorLeft + 4; - ng.ng_TopEdge = width + height; - ng.ng_Height = fonth + 6; - ng.ng_Width = (3*16 * fontw + 3*8 + 2*4) / 2 - 2; - ng.ng_GadgetText = NULL; - ng.ng_GadgetID = GID_STRING; - gad = CreateGadget (STRING_KIND,gad,&ng,GA_Disabled,TRUE,TAG_END); - strgad = gad; - - ng.ng_TopEdge = width; - ng.ng_Height += height; /* including string height */ - ng.ng_GadgetID = GID_LIST; - gad = CreateGadget (LISTVIEW_KIND,gad,&ng,GTLV_Labels,&lvlist,GTLV_ShowSelected,gad,TAG_END); - lvgad = gad; - - ng.ng_TopEdge += ng.ng_Height + 4; - ng.ng_Width = 16 * fontw + 8; - ng.ng_Height = fonth + 6; - /* - ng.ng_GadgetText = "Add"; - ng.ng_GadgetID = GID_ADD; - gad = CreateGadget (BUTTON_KIND,gad,&ng,TAG_END); - - ng.ng_LeftEdge += ng.ng_Width + 4; - ng.ng_GadgetText = "Remove"; - ng.ng_GadgetID = GID_REMOVE; - gad = CreateGadget (BUTTON_KIND,gad,&ng,TAG_END); - - ng.ng_LeftEdge += ng.ng_Width + 4; - ng.ng_GadgetText = "Sort"; - ng.ng_GadgetID = GID_SORT; - gad = CreateGadget (BUTTON_KIND,gad,&ng,TAG_END); - */ - - ng.ng_TopEdge += ng.ng_Height + 4; - ng.ng_LeftEdge = screen->WBorLeft + 4; - ng.ng_GadgetText = "Save"; - ng.ng_GadgetID = GID_SAVE; - gad = CreateGadget (BUTTON_KIND,gad,&ng,TAG_END); - - ng.ng_LeftEdge += ng.ng_Width + 4; - ng.ng_GadgetText = "Use"; - ng.ng_GadgetID = GID_USE; - gad = CreateGadget (BUTTON_KIND,gad,&ng,TAG_END); - - ng.ng_LeftEdge += ng.ng_Width + 4; - ng.ng_GadgetText = "Cancel"; - ng.ng_GadgetID = GID_CANCEL; - gad = CreateGadget (BUTTON_KIND,gad,&ng,TAG_END); - - // ********************************************************** // - - if (!gad) - { - Printf ("cannot create objects\n"); - FreeGadgets (glist); - UnlockPubScreen (NULL,screen); - exit(10); - } - - width = ng.ng_LeftEdge + ng.ng_Width + 4 + screen->WBorRight; - height = ng.ng_TopEdge + ng.ng_Height + 4 + screen->WBorBottom; - - qsort(locations, count, sizeof(struct Location), cmploc); - for (i = 0; i < count; i++) { - if (node = AllocVec (sizeof(struct Node) + strlen(locations[i].tz) + 1,MEMF_CLEAR)) - { - node->ln_Name = (STRPTR)(node + 1); - strcpy (node->ln_Name,locations[i].tz); - AddTail (&lvlist, node); - } - } - - if (window = OpenWindowTags (NULL, - WA_Title, "Time zone preferences", - WA_Width, width, - WA_Height, height, - WA_Left, (screen->Width - width) / 2, - WA_Top, (screen->Height - height) / 2, - WA_Flags,WFLG_CLOSEGADGET | WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_ACTIVATE, - WA_IDCMP,IDCMP_CLOSEWINDOW | IDCMP_VANILLAKEY | IDCMP_REFRESHWINDOW | BUTTONIDCMP | STRINGIDCMP | LISTVIEWIDCMP, - WA_PubScreen, screen, - WA_Gadgets, glist, - TAG_END)) - { - GT_RefreshWindow(window, NULL); - GT_SetGadgetAttrs(lvgad, window, NULL, GTLV_Labels, &lvlist, TAG_END); - - winsig = 1L << window->UserPort->mp_SigBit; - - // ********************************************************** // - - cont = TRUE; - do { - sigs = Wait(winsig | SIGBREAKF_CTRL_C); - - if (sigs & SIGBREAKF_CTRL_C) - cont = FALSE; - - if (sigs & winsig) - { - while (imsg = GT_GetIMsg (window->UserPort)) - { - switch (imsg->Class) { - case IDCMP_GADGETUP: - gad = (struct Gadget *) imsg->IAddress; - switch (gad->GadgetID) - { - case GID_CANCEL: - cont = FALSE; - break; - case GID_LIST: - GT_GetGadgetAttrs (lvgad,window,NULL,GTLV_Selected,&num,TAG_END); - if (node = get_node (&lvlist,num)) - { - GT_SetGadgetAttrs (strgad,window,NULL,GTST_String,node->ln_Name,GA_Disabled,FALSE,TAG_END); - ActivateGadget (strgad,window,NULL); - } - break; - case GID_STRING: - if (node) - { - GT_GetGadgetAttrs (strgad,window,NULL,GTST_String,&text,TAG_END); - GT_SetGadgetAttrs (lvgad,window,NULL,GTLV_Labels,-1,TAG_END); - node = replace_node_text (&lvlist,node,text); - GT_SetGadgetAttrs (lvgad,window,NULL,GTLV_Labels,&lvlist,TAG_END); - } - break; - } - break; - case IDCMP_VANILLAKEY: - if (imsg->Code == 0x1b) /* Esc */ - cont = FALSE; - break; - case IDCMP_REFRESHWINDOW: - GT_BeginRefresh(window); - GT_EndRefresh(window, TRUE); - break; - case IDCMP_CLOSEWINDOW: - cont = FALSE; - break; - } - GT_ReplyIMsg (imsg); - } - } - } while (cont); - - CloseWindow(window); - } - - FreeGadgets (glist); - UnlockPubScreen (NULL, screen); - - free_list(&lvlist); - - return (0); -}