aboutsummaryrefslogtreecommitdiff
path: root/libmap
diff options
context:
space:
mode:
Diffstat (limited to 'libmap')
-rw-r--r--libmap/Makefile.am1
-rw-r--r--libmap/Makefile.in1
-rw-r--r--libmap/README2
-rw-r--r--libmap/cc-timezone-map.c466
-rw-r--r--libmap/cc-timezone-map.h4
-rw-r--r--libmap/tz.c49
6 files changed, 512 insertions, 11 deletions
diff --git a/libmap/Makefile.am b/libmap/Makefile.am
index 0cdeb34..a10b835 100644
--- a/libmap/Makefile.am
+++ b/libmap/Makefile.am
@@ -2,6 +2,7 @@ uidir = $(pkgdatadir)/libmap/ui
dist_ui_DATA = \
data/bg.png \
data/cc.png \
+ data/olsen_map.png \
data/pin.png \
data/timezone_0.png \
data/timezone_-10.png \
diff --git a/libmap/Makefile.in b/libmap/Makefile.in
index b4ae6df..dd552a4 100644
--- a/libmap/Makefile.in
+++ b/libmap/Makefile.in
@@ -285,6 +285,7 @@ uidir = $(pkgdatadir)/libmap/ui
dist_ui_DATA = \
data/bg.png \
data/cc.png \
+ data/olsen_map.png \
data/pin.png \
data/timezone_0.png \
data/timezone_-10.png \
diff --git a/libmap/README b/libmap/README
index 70d6f6c..c83c6d8 100644
--- a/libmap/README
+++ b/libmap/README
@@ -2,4 +2,4 @@ This static library is a copied version of the code in GNOME 3.0's control cente
Ideally in the future, we can have all three packages using the same code. But for now, for time reasons (hah), it's just a copy.
-To update this copy, put newer versions of the code and data files in place; then fix up any GTK3-isms.
+To update this copy, put newer versions of the code and data files in place; then fix up any GTK3-isms and add cc_timezone_map_set_coords and friends.
diff --git a/libmap/cc-timezone-map.c b/libmap/cc-timezone-map.c
index 960a049..7647925 100644
--- a/libmap/cc-timezone-map.c
+++ b/libmap/cc-timezone-map.c
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2010 Intel, Inc
+ * Copyright (C) 2011 Canonical Ltd.
*
* Portions from Ubiquity, Copyright (C) 2009 Canonical Ltd.
* Written by Evan Dandrea <evand@ubuntu.com>
@@ -48,10 +49,15 @@ struct _CcTimezoneMapPrivate
GdkPixbuf *background;
GdkPixbuf *color_map;
+ GdkPixbuf *olsen_map;
guchar *visible_map_pixels;
gint visible_map_rowstride;
+ gint olsen_map_channels;
+ guchar *olsen_map_pixels;
+ gint olsen_map_rowstride;
+
gdouble selected_offset;
TzDB *tzdb;
@@ -111,6 +117,388 @@ static CcTimezoneMapOffset color_codes[] =
{-100, 0, 0, 0, 0 }
};
+static const gchar * olsen_map_timezones[] = {
+ "Africa/Abidjan",
+ "Africa/Accra",
+ "Africa/Addis_Ababa",
+ "Africa/Algiers",
+ "Africa/Asmara",
+ "Africa/Bamako",
+ "Africa/Bangui",
+ "Africa/Banjul",
+ "Africa/Bissau",
+ "Africa/Blantyre",
+ "Africa/Brazzaville",
+ "Africa/Bujumbura",
+ "Africa/Cairo",
+ "Africa/Casablanca",
+ "Africa/Conakry",
+ "Africa/Dakar",
+ "Africa/Dar_es_Salaam",
+ "Africa/Djibouti",
+ "Africa/Douala",
+ "Africa/El_Aaiun",
+ "Africa/Freetown",
+ "Africa/Gaborone",
+ "Africa/Harare",
+ "Africa/Johannesburg",
+ "Africa/Kampala",
+ "Africa/Khartoum",
+ "Africa/Kigali",
+ "Africa/Kinshasa",
+ "Africa/Lagos",
+ "Africa/Libreville",
+ "Africa/Lome",
+ "Africa/Luanda",
+ "Africa/Lubumbashi",
+ "Africa/Lusaka",
+ "Africa/Malabo",
+ "Africa/Maputo",
+ "Africa/Maseru",
+ "Africa/Mbabane",
+ "Africa/Mogadishu",
+ "Africa/Monrovia",
+ "Africa/Nairobi",
+ "Africa/Ndjamena",
+ "Africa/Niamey",
+ "Africa/Nouakchott",
+ "Africa/Ouagadougou",
+ "Africa/Porto-Novo",
+ "Africa/Sao_Tome",
+ "Africa/Tripoli",
+ "Africa/Tunis",
+ "Africa/Windhoek",
+ "America/Adak",
+ "America/Anguilla",
+ "America/Antigua",
+ "America/Araguaina",
+ "America/Argentina/Buenos_Aires",
+ "America/Argentina/Catamarca",
+ "America/Argentina/Cordoba",
+ "America/Argentina/Jujuy",
+ "America/Argentina/La_Rioja",
+ "America/Argentina/Mendoza",
+ "America/Argentina/Rio_Gallegos",
+ "America/Argentina/San_Juan",
+ "America/Argentina/San_Luis",
+ "America/Argentina/Tucuman",
+ "America/Argentina/Ushuaia",
+ "America/Aruba",
+ "America/Asuncion",
+ "America/Atikokan",
+ "America/Bahia",
+ "America/Barbados",
+ "America/Belem",
+ "America/Belize",
+ "America/Blanc-Sablon",
+ "America/Boa_Vista",
+ "America/Bogota",
+ "America/Boise",
+ "America/Cambridge_Bay",
+ "America/Campo_Grande",
+ "America/Cancun",
+ "America/Caracas",
+ "America/Cayenne",
+ "America/Cayman",
+ "America/Chicago",
+ "America/Chihuahua",
+ "America/Coral_Harbour",
+ "America/Costa_Rica",
+ "America/Cuiaba",
+ "America/Curacao",
+ "America/Dawson",
+ "America/Dawson_Creek",
+ "America/Denver",
+ "America/Dominica",
+ "America/Edmonton",
+ "America/Eirunepe",
+ "America/El_Salvador",
+ "America/Fortaleza",
+ "America/Glace_Bay",
+ "America/Goose_Bay",
+ "America/Grand_Turk",
+ "America/Grenada",
+ "America/Guadeloupe",
+ "America/Guatemala",
+ "America/Guayaquil",
+ "America/Guyana",
+ "America/Halifax",
+ "America/Havana",
+ "America/Hermosillo",
+ "America/Indiana/Indianapolis",
+ "America/Indiana/Knox",
+ "America/Indiana/Marengo",
+ "America/Indiana/Petersburg",
+ "America/Indiana/Vevay",
+ "America/Indiana/Vincennes",
+ "America/Indiana/Winamac",
+ "America/Inuvik",
+ "America/Iqaluit",
+ "America/Jamaica",
+ "America/Juneau",
+ "America/Kentucky/Louisville",
+ "America/Kentucky/Monticello",
+ "America/La_Paz",
+ "America/Lima",
+ "America/Los_Angeles",
+ "America/Maceio",
+ "America/Managua",
+ "America/Manaus",
+ "America/Marigot",
+ "America/Martinique",
+ "America/Mazatlan",
+ "America/Menominee",
+ "America/Merida",
+ "America/Mexico_City",
+ "America/Miquelon",
+ "America/Moncton",
+ "America/Monterrey",
+ "America/Montevideo",
+ "America/Montreal",
+ "America/Montserrat",
+ "America/Nassau",
+ "America/New_York",
+ "America/Nipigon",
+ "America/Noronha",
+ "America/North_Dakota/Center",
+ "America/North_Dakota/Salem",
+ "America/Panama",
+ "America/Pangnirtung",
+ "America/Paramaribo",
+ "America/Phoenix",
+ "America/Port-au-Prince",
+ "America/Port_of_Spain",
+ "America/Porto_Velho",
+ "America/Puerto_Rico",
+ "America/Rainy_River",
+ "America/Rankin_Inlet",
+ "America/Recife",
+ "America/Regina",
+ "America/Resolute",
+ "America/Rio_Branco",
+ "America/Santarem",
+ "America/Santiago",
+ "America/Santo_Domingo",
+ "America/Sao_Paulo",
+ "America/St_Barthelemy",
+ "America/St_Johns",
+ "America/St_Kitts",
+ "America/St_Lucia",
+ "America/St_Thomas",
+ "America/St_Vincent",
+ "America/Tegucigalpa",
+ "America/Thunder_Bay",
+ "America/Tijuana",
+ "America/Toronto",
+ "America/Tortola",
+ "America/Vancouver",
+ "America/Whitehorse",
+ "America/Winnipeg",
+ "America/Yellowknife",
+ "Ameriica/Swift_Current",
+ "Arctic/Longyearbyen",
+ "Asia/Aden",
+ "Asia/Almaty",
+ "Asia/Amman",
+ "Asia/Anadyr",
+ "Asia/Aqtau",
+ "Asia/Aqtobe",
+ "Asia/Ashgabat",
+ "Asia/Baghdad",
+ "Asia/Bahrain",
+ "Asia/Baku",
+ "Asia/Bangkok",
+ "Asia/Beirut",
+ "Asia/Bishkek",
+ "Asia/Brunei",
+ "Asia/Choibalsan",
+ "Asia/Chongqing",
+ "Asia/Colombo",
+ "Asia/Damascus",
+ "Asia/Dhaka",
+ "Asia/Dili",
+ "Asia/Dubai",
+ "Asia/Dushanbe",
+ "Asia/Gaza",
+ "Asia/Harbin",
+ "Asia/Ho_Chi_Minh",
+ "Asia/Hong_Kong",
+ "Asia/Hovd",
+ "Asia/Irkutsk",
+ "Asia/Jakarta",
+ "Asia/Jayapura",
+ "Asia/Jerusalem",
+ "Asia/Kabul",
+ "Asia/Kamchatka",
+ "Asia/Karachi",
+ "Asia/Kashgar",
+ "Asia/Katmandu",
+ "Asia/Kolkata",
+ "Asia/Krasnoyarsk",
+ "Asia/Kuala_Lumpur",
+ "Asia/Kuching",
+ "Asia/Kuwait",
+ "Asia/Macau",
+ "Asia/Magadan",
+ "Asia/Makassar",
+ "Asia/Manila",
+ "Asia/Muscat",
+ "Asia/Nicosia",
+ "Asia/Novosibirsk",
+ "Asia/Omsk",
+ "Asia/Oral",
+ "Asia/Phnom_Penh",
+ "Asia/Pontianak",
+ "Asia/Pyongyang",
+ "Asia/Qatar",
+ "Asia/Qyzylorda",
+ "Asia/Rangoon",
+ "Asia/Riyadh",
+ "Asia/Sakhalin",
+ "Asia/Samarkand",
+ "Asia/Seoul",
+ "Asia/Shanghai",
+ "Asia/Singapore",
+ "Asia/Taipei",
+ "Asia/Tashkent",
+ "Asia/Tbilisi",
+ "Asia/Tehran",
+ "Asia/Thimphu",
+ "Asia/Tokyo",
+ "Asia/Ulaanbaatar",
+ "Asia/Urumqi",
+ "Asia/Vientiane",
+ "Asia/Vladivostok",
+ "Asia/Yakutsk",
+ "Asia/Yekaterinburg",
+ "Asia/Yerevan",
+ "Atlantic/Azores",
+ "Atlantic/Bermuda",
+ "Atlantic/Canary",
+ "Atlantic/Cape_Verde",
+ "Atlantic/Faroe",
+ "Atlantic/Madeira",
+ "Atlantic/Reykjavik",
+ "Atlantic/South_Georgia",
+ "Atlantic/St_Helena",
+ "Atlantic/Stanley",
+ "Australia/Adelaide",
+ "Australia/Brisbane",
+ "Australia/Broken_Hill",
+ "Australia/Currie",
+ "Australia/Darwin",
+ "Australia/Eucla",
+ "Australia/Hobart",
+ "Australia/Lindeman",
+ "Australia/Lord_Howe",
+ "Australia/Melbourne",
+ "Australia/Perth",
+ "Australia/Sydney",
+ "Europe/Amsterdam",
+ "Europe/Andorra",
+ "Europe/Athens",
+ "Europe/Belgrade",
+ "Europe/Berlin",
+ "Europe/Bratislava",
+ "Europe/Brussels",
+ "Europe/Bucharest",
+ "Europe/Budapest",
+ "Europe/Chisinau",
+ "Europe/Copenhagen",
+ "Europe/Dublin",
+ "Europe/Gibraltar",
+ "Europe/Guernsey",
+ "Europe/Helsinki",
+ "Europe/Isle_of_Man",
+ "Europe/Istanbul",
+ "Europe/Jersey",
+ "Europe/Kaliningrad",
+ "Europe/Kiev",
+ "Europe/Lisbon",
+ "Europe/Ljubljana",
+ "Europe/London",
+ "Europe/Luxembourg",
+ "Europe/Madrid",
+ "Europe/Malta",
+ "Europe/Marienhamn",
+ "Europe/Minsk",
+ "Europe/Monaco",
+ "Europe/Moscow",
+ "Europe/Oslo",
+ "Europe/Paris",
+ "Europe/Podgorica",
+ "Europe/Prague",
+ "Europe/Riga",
+ "Europe/Rome",
+ "Europe/Samara",
+ "Europe/San_Marino",
+ "Europe/Sarajevo",
+ "Europe/Simferopol",
+ "Europe/Skopje",
+ "Europe/Sofia",
+ "Europe/Stockholm",
+ "Europe/Tallinn",
+ "Europe/Tirane",
+ "Europe/Uzhgorod",
+ "Europe/Vaduz",
+ "Europe/Vatican",
+ "Europe/Vienna",
+ "Europe/Vilnius",
+ "Europe/Volgograd",
+ "Europe/Warsaw",
+ "Europe/Zagreb",
+ "Europe/Zaporozhye",
+ "Europe/Zurich",
+ "Indian/Antananarivo",
+ "Indian/Chagos",
+ "Indian/Christmas",
+ "Indian/Cocos",
+ "Indian/Comoro",
+ "Indian/Kerguelen",
+ "Indian/Mahe",
+ "Indian/Maldives",
+ "Indian/Mauritius",
+ "Indian/Mayotte",
+ "Indian/Reunion",
+ "Pacific/Apia",
+ "Pacific/Auckland",
+ "Pacific/Chatham",
+ "Pacific/Easter",
+ "Pacific/Efate",
+ "Pacific/Enderbury",
+ "Pacific/Fakaofo",
+ "Pacific/Fiji",
+ "Pacific/Funafuti",
+ "Pacific/Galapagos",
+ "Pacific/Gambier",
+ "Pacific/Guadalcanal",
+ "Pacific/Guam",
+ "Pacific/Honolulu",
+ "Pacific/Johnston",
+ "Pacific/Kiritimati",
+ "Pacific/Kosrae",
+ "Pacific/Kwajalein",
+ "Pacific/Majuro",
+ "Pacific/Marquesas",
+ "Pacific/Midway",
+ "Pacific/Nauru",
+ "Pacific/Niue",
+ "Pacific/Norfolk",
+ "Pacific/Noumea",
+ "Pacific/Pago_Pago",
+ "Pacific/Palau",
+ "Pacific/Pitcairn",
+ "Pacific/Ponape",
+ "Pacific/Port_Moresby",
+ "Pacific/Rarotonga",
+ "Pacific/Saipan",
+ "Pacific/Tahiti",
+ "Pacific/Tarawa",
+ "Pacific/Tongatapu",
+ "Pacific/Truk",
+ "Pacific/Wake",
+ "Pacific/Wallis"
+};
static void
cc_timezone_map_get_property (GObject *object,
@@ -155,6 +543,16 @@ cc_timezone_map_dispose (GObject *object)
priv->orig_color_map = NULL;
}
+ if (priv->olsen_map)
+ {
+ g_object_unref (priv->olsen_map);
+ priv->olsen_map = NULL;
+
+ priv->olsen_map_channels = 0;
+ priv->olsen_map_pixels = NULL;
+ priv->olsen_map_rowstride = 0;
+ }
+
if (priv->background)
{
g_object_unref (priv->background);
@@ -513,12 +911,10 @@ set_location (CcTimezoneMap *map,
tz_info_free (info);
}
-static gboolean
-button_press_event (GtkWidget *widget,
- GdkEventButton *event)
+static TzLocation *
+get_loc_for_xy (GtkWidget * widget, gint x, gint y)
{
CcTimezoneMapPrivate *priv = CC_TIMEZONE_MAP (widget)->priv;
- gint x, y;
guchar r, g, b, a;
guchar *pixels;
gint rowstride;
@@ -529,10 +925,6 @@ button_press_event (GtkWidget *widget,
GList *distances = NULL;
GtkAllocation alloc;
- x = event->x;
- y = event->y;
-
-
rowstride = priv->visible_map_rowstride;
pixels = priv->visible_map_pixels;
@@ -578,11 +970,19 @@ button_press_event (GtkWidget *widget,
}
distances = g_list_sort (distances, (GCompareFunc) sort_locations);
-
- set_location (CC_TIMEZONE_MAP (widget), (TzLocation*) distances->data);
+ TzLocation * loc = (TzLocation*) distances->data;
g_list_free (distances);
+ return loc;
+}
+
+static gboolean
+button_press_event (GtkWidget *widget,
+ GdkEventButton *event)
+{
+ TzLocation * loc = get_loc_for_xy (widget, event->x, event->y);
+ set_location (CC_TIMEZONE_MAP (widget), loc);
return TRUE;
}
@@ -664,6 +1064,18 @@ cc_timezone_map_init (CcTimezoneMap *self)
g_clear_error (&err);
}
+ priv->olsen_map = gdk_pixbuf_new_from_file (DATADIR "/olsen_map.png",
+ &err);
+ if (!priv->olsen_map)
+ {
+ g_warning ("Could not load olsen map: %s",
+ (err) ? err->message : "Unknown error");
+ g_clear_error (&err);
+ }
+ priv->olsen_map_channels = gdk_pixbuf_get_n_channels (priv->olsen_map);
+ priv->olsen_map_pixels = gdk_pixbuf_get_pixels (priv->olsen_map);
+ priv->olsen_map_rowstride = gdk_pixbuf_get_rowstride (priv->olsen_map);
+
priv->tzdb = tz_load_db ();
g_signal_connect (self, "button-press-event", G_CALLBACK (button_press_event),
@@ -704,6 +1116,40 @@ cc_timezone_map_set_timezone (CcTimezoneMap *map,
gtk_widget_queue_draw (GTK_WIDGET (map));
}
+void
+cc_timezone_map_set_coords (CcTimezoneMap *map, gdouble lon, gdouble lat)
+{
+ const gchar * zone = cc_timezone_map_get_timezone_at_coords (map, lon, lat);
+ cc_timezone_map_set_timezone (map, zone);
+}
+
+const gchar *
+cc_timezone_map_get_timezone_at_coords (CcTimezoneMap *map, gdouble lon, gdouble lat)
+{
+ gint x = (int)(2048.0 / 360.0 * (180.0 + lon));
+ gint y = (int)(1024.0 / 180.0 * (90.0 - lat));
+ gint offset = map->priv->olsen_map_rowstride * y + x * map->priv->olsen_map_channels;
+ guchar color0 = map->priv->olsen_map_pixels[offset];
+ guchar color1 = map->priv->olsen_map_pixels[offset + 1];
+ gint zone = ((color0 & 248) << 1) + ((color1 >>4) & 15);
+
+ const gchar * city = NULL;
+ if (zone < G_N_ELEMENTS(olsen_map_timezones))
+ city = olsen_map_timezones[zone];
+
+ if (city != NULL) {
+ return city;
+ }
+ else {
+ GtkAllocation alloc;
+ gtk_widget_get_allocation (GTK_WIDGET (map), &alloc);
+ x = convert_longtitude_to_x(lon, alloc.width);
+ y = convert_latitude_to_y(lat, alloc.height);
+ TzLocation * loc = get_loc_for_xy(GTK_WIDGET (map), x, y);
+ return loc->zone;
+ }
+}
+
TzLocation *
cc_timezone_map_get_location (CcTimezoneMap *map)
{
diff --git a/libmap/cc-timezone-map.h b/libmap/cc-timezone-map.h
index 3c57b27..8de986d 100644
--- a/libmap/cc-timezone-map.h
+++ b/libmap/cc-timezone-map.h
@@ -72,6 +72,10 @@ CcTimezoneMap *cc_timezone_map_new (void);
void cc_timezone_map_set_timezone (CcTimezoneMap *map,
const gchar *timezone);
+void cc_timezone_map_set_coords (CcTimezoneMap *map,
+ gdouble lon, gdouble lat);
+const gchar * cc_timezone_map_get_timezone_at_coords (CcTimezoneMap *map,
+ gdouble lon, gdouble lat);
TzLocation * cc_timezone_map_get_location (CcTimezoneMap *map);
G_END_DECLS
diff --git a/libmap/tz.c b/libmap/tz.c
index 3e6c8ae..b77a8ef 100644
--- a/libmap/tz.c
+++ b/libmap/tz.c
@@ -146,6 +146,55 @@ tz_db_free (TzDB *db)
g_free (db);
}
+static gint
+sort_locations (TzLocation *a,
+ TzLocation *b)
+{
+ if (a->dist > b->dist)
+ return 1;
+
+ if (a->dist < b->dist)
+ return -1;
+
+ return 0;
+}
+
+static gdouble
+convert_longtitude_to_x (gdouble longitude, gint map_width)
+{
+ const gdouble xdeg_offset = -6;
+ gdouble x;
+
+ x = (map_width * (180.0 + longitude) / 360.0)
+ + (map_width * xdeg_offset / 180.0);
+
+ return x;
+}
+
+static gdouble
+radians (gdouble degrees)
+{
+ return (degrees / 360.0) * G_PI * 2;
+}
+
+static gdouble
+convert_latitude_to_y (gdouble latitude, gdouble map_height)
+{
+ gdouble bottom_lat = -59;
+ gdouble top_lat = 81;
+ gdouble top_per, y, full_range, top_offset, map_range;
+
+ top_per = top_lat / 180.0;
+ y = 1.25 * log (tan (G_PI_4 + 0.4 * radians (latitude)));
+ full_range = 4.6068250867599998;
+ top_offset = full_range * top_per;
+ map_range = fabs (1.25 * log (tan (G_PI_4 + 0.4 * radians (bottom_lat))) - top_offset);
+ y = fabs (y - top_offset);
+ y = y / map_range;
+ y = y * map_height;
+ return y;
+}
+
GPtrArray *
tz_get_locations (TzDB *db)
{