diff options
Diffstat (limited to 'abs')
-rw-r--r-- | abs/core-testing/LinHES-timezone/PKGBUILD | 4 | ||||
-rw-r--r-- | abs/core-testing/LinHES-timezone/linhes_timezone.c | 364 |
2 files changed, 295 insertions, 73 deletions
diff --git a/abs/core-testing/LinHES-timezone/PKGBUILD b/abs/core-testing/LinHES-timezone/PKGBUILD index ffad3a9..0b0d2ad 100644 --- a/abs/core-testing/LinHES-timezone/PKGBUILD +++ b/abs/core-testing/LinHES-timezone/PKGBUILD @@ -2,7 +2,7 @@ # Maintainer: Greg Frost <gregfrost1@bigpond.com> pkgname=LinHES-timezone pkgver=1 -pkgrel=5 +pkgrel=6 pkgdesc="GUI timezone selector used by LinHES-config." arch=i686 depends=() @@ -27,4 +27,4 @@ md5sums=('53976e51e938c555f84b43c933339051' '0d9e51af5f650dd329edce4531c42a58' 'c01e2335603d8395004e32bae9060fde' 'b20bd68272644f607fbfe7d50e7be42a' - 'b35602b7330c32a472223b22d95a1d6c') + '448ffca8f38b2dcd989e599ff2057399') diff --git a/abs/core-testing/LinHES-timezone/linhes_timezone.c b/abs/core-testing/LinHES-timezone/linhes_timezone.c index 024560f..ff75549 100644 --- a/abs/core-testing/LinHES-timezone/linhes_timezone.c +++ b/abs/core-testing/LinHES-timezone/linhes_timezone.c @@ -2,6 +2,8 @@ #include <math.h> #include <stdlib.h> #include <stdio.h> +#define _GNU_SOURCE +#include <string.h> #include <strings.h> #include <X11/Xlib.h> #include <X11/Intrinsic.h> @@ -49,6 +51,41 @@ double lat_rotate[2] = {1, 0}; double acceleration = 0.01; char input_keys[200]; +int guessing_timezone = FALSE; + +void select_place (int place) +{ + target_lon = atan2 (zone_data[selected_zone].place_info[place].v.y, + zone_data[selected_zone].place_info[place].v.x); + target_lat = acos (zone_data[selected_zone].place_info[place].v.z /2); + + selected_place = place; +} + +void default_zone (char *arg_zone) +{ + int found_zone = FALSE; + + for (int zone = 0; zone < NUM_ZONES; zone++) + { + for (int place = 0; place < zone_data[zone].num_places; place++) + { + if (strstr (zone_data[zone].place_info[place].zonename, + arg_zone[0] ? arg_zone : "Los_Angeles")) + { + selected_zone = zone; + select_place (place); + found_zone = TRUE; + } + } + } + + if (!found_zone) + { + default_zone (""); + } +} + int translate_point (vect_type *v, XPoint *p) { vect_type v2; @@ -259,53 +296,53 @@ void redraw_map () for (int zone = 0; zone < NUM_ZONES - 1; zone++) draw_zone (pixmap, zone, 0, 0); - draw_zone (pixmap, selected_zone, 1, 1); - XSetForeground (display, gc, selected_border.pixel); - draw_zone (pixmap, selected_zone, 0, 1); - - for (int place = 0; place < zone_data[selected_zone].num_places; place++) + if (guessing_timezone) { - XPoint point; + char *s = "Guessing Timezone"; + int text_width = XTextWidth (font, s, strlen (s)); + draw_string (width/2 - text_width/2, height/2, s, name_colour.pixel); + } + else + { + draw_zone (pixmap, selected_zone, 1, 1); + XSetForeground (display, gc, selected_border.pixel); + draw_zone (pixmap, selected_zone, 0, 1); - translate_point (&zone_data[selected_zone].place_info[place].v, &point); + for (int place = 0; place < zone_data[selected_zone].num_places; place++) + { + XPoint point; + + translate_point (&zone_data[selected_zone].place_info[place].v, &point); - draw_point (point, NULL); + draw_point (point, NULL); - if (place == selected_place) - { - char *underscore; - selected_point = point; - strcpy (selected_name, strchr (zone_data[selected_zone].place_info[place].zonename, '/') + 1); - while (underscore = strchr (selected_name, '_')) - underscore[0] = ' '; + if ((place == selected_place) && (!guessing_timezone)) + { + char *underscore; + selected_point = point; + strcpy (selected_name, strchr (zone_data[selected_zone].place_info[place].zonename, '/') + 1); + while (underscore = strchr (selected_name, '_')) + underscore[0] = ' '; + } } - } - draw_point (selected_point, selected_name); + draw_point (selected_point, selected_name); - { - char zone_offset[100]; - sprintf (zone_offset, "UTC%s", zone_data[selected_zone].offset); - draw_string ( - ((width * 0.95 - XTextWidth (font, zone_offset, strlen (zone_offset))) + - ((width / 2) + radius / sqrt (2))) / 2, - ((lrint (height * 0.05) + font->ascent) + - (height / 2 - radius / sqrt (2))) / 2, - zone_offset, name_colour.pixel); + { + char zone_offset[100]; + sprintf (zone_offset, "UTC%s", zone_data[selected_zone].offset); + draw_string ( + ((width * 0.95 - XTextWidth (font, zone_offset, strlen (zone_offset))) + + ((width / 2) + radius / sqrt (2))) / 2, + ((lrint (height * 0.05) + font->ascent) + + (height / 2 - radius / sqrt (2))) / 2, + zone_offset, name_colour.pixel); + } } XCopyArea (display, pixmap, window, gc, 0, 0, width, height, 0, 0); } -void select_place (int place) -{ - target_lon = atan2 (zone_data[selected_zone].place_info[place].v.y, - zone_data[selected_zone].place_info[place].v.x); - target_lat = acos (zone_data[selected_zone].place_info[place].v.z /2); - - selected_place = place; -} - int nearest_z (double near_z) { double min_delta = @@ -417,31 +454,37 @@ void next_view () double lat_error = target_lat - displayed_lat; double lon_error = target_lon - displayed_lon; - lat_error = atan2 (sin (lat_error), cos( lat_error)); - lon_error = atan2 (sin (lon_error), cos (lon_error)); - - error_total = sqrt (lat_error * lat_error + lon_error * lon_error); - - if (error_total < acceleration) + if (guessing_timezone) { - displayed_lat = target_lat; - displayed_lon = target_lon; + displayed_lon += 1 / 180.0 * M_PI; } else { - if (error_total > (step_size + acceleration) * - (step_size + acceleration) / acceleration / 2) - step_size += acceleration; + lat_error = atan2 (sin (lat_error), cos( lat_error)); + lon_error = atan2 (sin (lon_error), cos (lon_error)); + + error_total = sqrt (lat_error * lat_error + lon_error * lon_error); + + if (error_total < acceleration) + { + displayed_lat = target_lat; + displayed_lon = target_lon; + } else - step_size -= acceleration; + { + if (error_total > (step_size + acceleration) * + (step_size + acceleration) / acceleration / 2) + step_size += acceleration; + else + step_size -= acceleration; - if (step_size < acceleration) - step_size = acceleration; + if (step_size < acceleration) + step_size = acceleration; - displayed_lat += step_size * (lat_error / error_total); - displayed_lon += step_size * (lon_error / error_total); + displayed_lat += step_size * (lat_error / error_total); + displayed_lon += step_size * (lon_error / error_total); + } } - } void *lirc_thread (void *unused) @@ -493,6 +536,176 @@ void *lirc_thread (void *unused) } } +void get_value (FILE *input, char*output, int out_len) +{ + const char *value_pattern = "value=\""; + char *value; + + output[0] = 0; + fgets (output, out_len, input); + + if (value = strcasestr (output, value_pattern)) + { + memmove (output, value + strlen (value_pattern), + strlen (value + strlen (value_pattern)) + 1); + } + + if (value = strchr (output, '"')) + value[0] = 0; +} + +void *timezone_guess (void *unused) +{ + const double invalid = 99999; + FILE *guess_data; + char line_in[1000]; + double guess_latitude = invalid; + double guess_longitude = invalid; + char guess_zone[1000] = {0}; + char *timezone_info_command; + + if (getenv ("FAKE_GEOBYTES")) + { + timezone_info_command = + "sleep 2 ; " + "echo Latitude ; " + "echo \" <td value=\\\"-34.993\\\"\" ;" + "echo Longitude ; " + "echo \" <td value=\\\"138.6\\\"\" ;" + "echo TimeZone ; " + "echo \" <td value=\\\"+09:30\\\"\""; + } + else + { + timezone_info_command = + "wget http://www.geobytes.com/IpLocator.htm -O - 2> /dev/null |" + "grep \"^ <td \" |" + "grep -i -E -A1 \"Latitude|Longitude|TimeZone\" | grep -v \"^--$\""; + } + + guess_data = popen (timezone_info_command, "r"); + + if (!guess_data) + { + fprintf (stderr, "error parsing web page for timezone guess\n"); + guessing_timezone = FALSE; + return NULL; + } + + while (fgets (line_in, sizeof (line_in), guess_data)) + { + // Look for the entries in the guess data and then the next line + // will hold the value. + + if (strcasestr (line_in, "latitude")) + { + get_value (guess_data, line_in, sizeof (line_in)); + sscanf (line_in, "%lf", &guess_latitude); + } + else if (strcasestr (line_in, "longitude")) + { + get_value (guess_data, line_in, sizeof (line_in)); + sscanf (line_in, "%lf", &guess_longitude); + } + else if (strcasestr (line_in, "timezone")) + { + get_value (guess_data, line_in, sizeof (line_in)); + + // The geobytes timezone data is of the form "+09:30" whereas the + // map timezone data is of the form "+6" or "+9.5". Convert + // to the map timezone data format so we can find the timezone. + + if (strcmp (&line_in[3], ":30") == 0) + sprintf (&line_in[3], ".5"); + else + line_in[3] = 0; + + if (line_in[1] == '0') + memmove (&line_in[1], &line_in[2], strlen (&line_in[2]) + 1); + + strncpy (guess_zone, line_in, sizeof (guess_zone)); + } + } + + pclose (guess_data); + + if ((guess_latitude != invalid) && + (guess_longitude != invalid) && + guess_zone[0] != 0) + { + int zone; + + fprintf (stderr, "guessed lat lon %f %f %s\n", + guess_latitude, guess_longitude, guess_zone); + + // Look for the guessed zone in the zone_data structure. + for (zone = 0; zone < NUM_ZONES; zone++) + { + if (strcmp (guess_zone, zone_data[zone].offset) == 0) + break; + } + + if (zone == NUM_ZONES) + { + fprintf (stderr, "couldnt find zone %s\n", guess_zone); + default_zone (""); + } + else + { + double x,y,z; + double min_dist_squared; + int closest_place; + + // Look for the location in the zone nearest to the guess lat/lon. + + // Convert the guessed lat/lon to x,y,z. + + guess_latitude *= M_PI / 180.0; + guess_longitude *= M_PI / 180.0; + + x = cos (guess_longitude) * cos (guess_latitude); + y = sin (guess_longitude) * cos (guess_latitude); + z = sin (guess_latitude); + + min_dist_squared = + pow (x - zone_data[zone].place_info[0].v.x, 2) + + pow (y - zone_data[zone].place_info[0].v.y, 2) + + pow (z - zone_data[zone].place_info[0].v.z, 2); + closest_place = 0; + + for (int place = 1; place < zone_data[zone].num_places; place++) + { + double dist_squared; + + dist_squared = + pow (x - zone_data[zone].place_info[place].v.x, 2) + + pow (y - zone_data[zone].place_info[place].v.y, 2) + + pow (z - zone_data[zone].place_info[place].v.z, 2); + + if (dist_squared < min_dist_squared) + { + closest_place = place; + min_dist_squared = dist_squared; + } + } + + fprintf (stderr, "Guess=%s %s\n", + zone_data[zone].place_info[closest_place].zonename, + zone_data[zone].offset); + + selected_zone = zone; + select_place (closest_place); + } + } + else + { + default_zone (""); + } + + guessing_timezone = FALSE; + return NULL; +} + void remove_titlebar_and_borders () { XClassHint* classHint; @@ -547,7 +760,7 @@ int main (int argc, char *argv[]) int arg_width = -1; int arg_height = -1; char arg_zone[100] = {0}; - + if (getenv ("ACCEL")) acceleration = atof (getenv ("ACCEL")); @@ -557,6 +770,13 @@ int main (int argc, char *argv[]) { case 'z': strncpy (arg_zone, optarg, sizeof (arg_zone) - 1); + + if (strcasecmp (arg_zone, "guess") == 0) + { + guessing_timezone = TRUE; + arg_zone[0]=0; + } + break; case 'w': @@ -574,14 +794,16 @@ int main (int argc, char *argv[]) case '?': printf ("usage: %s [-a accelleration] [-z timezone] " "[-w width] [-h height]\n" - "e.g. linhes_timezone -w 1920 -h 1090 -z Australia/Adelaide\n", + "e.g. linhes_timezone -w 1920 -h 1090 -z Australia/Adelaide\n" + "specify a timezone of 'guess' to determine the initial " + "timezone from\n" + "your ip address using geocache.\n", argv[0]); exit (0); break; } } - pthread_create (&tid, NULL, lirc_thread, NULL); /* Connect to the X server. */ @@ -636,7 +858,6 @@ int main (int argc, char *argv[]) remove_titlebar_and_borders (); - if (!window) { fprintf (stderr, "cannot open window\n"); @@ -726,21 +947,21 @@ int main (int argc, char *argv[]) if (XAllocColor (display, cmap, &location_dot) == 0) printf ("Cant allocate color\n"); - // Find LA and make that the selected zone and place. - - for (int zone = 0; zone < NUM_ZONES; zone++) + // Find the selected timezone (or LA if a timezone was not selected) and + // make that the selected zone and place. + + default_zone (arg_zone); + + if (guessing_timezone) { - for (int place = 0; place < zone_data[zone].num_places; place++) - { - if (strstr (zone_data[zone].place_info[place].zonename, - arg_zone[0] ? arg_zone : "Los_Angeles")) - { - selected_zone = zone; - select_place (place); - displayed_lat = target_lat; - displayed_lon = target_lon; - } - } + pthread_create (&tid, NULL, timezone_guess, NULL); + displayed_lat = M_PI/2; + displayed_lon = 0; + } + else + { + displayed_lat = target_lat; + displayed_lon = target_lon; } /* ask for exposure event and keyboard events */ @@ -753,7 +974,8 @@ int main (int argc, char *argv[]) while (1) { - if ((displayed_lat != target_lat) || (displayed_lon != target_lon)) + if ((displayed_lat != target_lat) || (displayed_lon != target_lon) || + guessing_timezone) { next_view (); redraw_map (); |