summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUnconfigured <Unconfigured>2009-07-09 04:43:40 (GMT)
committerUnconfigured <Unconfigured>2009-07-09 04:43:40 (GMT)
commitabae5612155504ff82912331e9a586dafcab41f4 (patch)
treebb8230b505e67f8e3c5038afd823e2e7593dc5af
parentf2bd34879a8ce975011dc1a0473c1cd0a3096a52 (diff)
downloadlinhes_pkgbuild-abae5612155504ff82912331e9a586dafcab41f4.zip
linhes_pkgbuild-abae5612155504ff82912331e9a586dafcab41f4.tar.gz
linhes_pkgbuild-abae5612155504ff82912331e9a586dafcab41f4.tar.bz2
LinHES-timezone: Add -z guess option to auto-detect timezone from IP addr
-rw-r--r--abs/core-testing/LinHES-timezone/PKGBUILD4
-rw-r--r--abs/core-testing/LinHES-timezone/linhes_timezone.c364
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 ();