diff options
| author | Unconfigured <Unconfigured> | 2009-07-09 04:43:40 (GMT) | 
|---|---|---|
| committer | Unconfigured <Unconfigured> | 2009-07-09 04:43:40 (GMT) | 
| commit | abae5612155504ff82912331e9a586dafcab41f4 (patch) | |
| tree | bb8230b505e67f8e3c5038afd823e2e7593dc5af /abs/core-testing | |
| parent | f2bd34879a8ce975011dc1a0473c1cd0a3096a52 (diff) | |
| download | linhes_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
Diffstat (limited to 'abs/core-testing')
| -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 (); | 
