Remove gnome-panel-02-workspace-switcher.diff : #127285, applied upstream.
Re-Order the rest of the patches
--- a/ChangeLog Fri Oct 20 15:24:25 2006 +0000
+++ b/ChangeLog Fri Oct 20 15:31:04 2006 +0000
@@ -1,3 +1,10 @@
+2006-10-20 Matt Keenan <[email protected]>
+
+ * gnome-panel.spec : Remove 02-workspace-switcher.diff, re-order patches
+ * patches/gnome-panel-02-workspace-switcher.diff : Removed fixed in gconf
+ upstream
+ * patches/gnome-panel-*.diff : Re-Order numbers
+
2006-10-20 Erwann Chenede - <[email protected]>
* patches/metacity-08-pretty-function.diff
--- a/gnome-panel.spec Fri Oct 20 15:24:25 2006 +0000
+++ b/gnome-panel.spec Fri Oct 20 15:31:04 2006 +0000
@@ -22,22 +22,21 @@
Source6: libpanel-applet-2.3.gz
Source7: world_map-960.png
Patch1: gnome-panel-01-default-setup.diff
-Patch2: gnome-panel-02-workspace-switcher.diff
-Patch3: gnome-panel-03-fish-applet.diff
-Patch4: gnome-panel-04-concurrent-login.diff
-Patch5: gnome-panel-05-panel-applet-session-never-restart.diff
-Patch6: gnome-panel-06-notificationarea-tooltip.diff
-Patch7: gnome-panel-07-input-method-filter-keypress.diff
-Patch8: gnome-panel-08-restrict-app-launching.diff
-Patch9: gnome-panel-09-launch-menu.diff
-Patch10: gnome-panel-10-solaris-branding.diff
-Patch11: gnome-panel-11-clock-timezone.diff
-Patch12: gnome-panel-12-trusted-extensions.diff
-Patch13: gnome-panel-13-noswitchuser.diff
-Patch14: gnome-panel-14-lockdown-applets.diff
-Patch15: gnome-panel-15-support-alacarte.diff
-Patch16: gnome-panel-16-lXau.diff
-Patch17: gnome-panel-17-preferences-menu.diff
+Patch2: gnome-panel-02-fish-applet.diff
+Patch3: gnome-panel-03-concurrent-login.diff
+Patch4: gnome-panel-04-panel-applet-session-never-restart.diff
+Patch5: gnome-panel-05-notificationarea-tooltip.diff
+Patch6: gnome-panel-06-input-method-filter-keypress.diff
+Patch7: gnome-panel-07-restrict-app-launching.diff
+Patch8: gnome-panel-08-launch-menu.diff
+Patch9: gnome-panel-09-solaris-branding.diff
+Patch10: gnome-panel-10-clock-timezone.diff
+Patch11: gnome-panel-11-trusted-extensions.diff
+Patch12: gnome-panel-12-noswitchuser.diff
+Patch13: gnome-panel-13-lockdown-applets.diff
+Patch14: gnome-panel-14-support-alacarte.diff
+Patch15: gnome-panel-15-lXau.diff
+Patch16: gnome-panel-16-preferences-menu.diff
URL: http://www.gnome.org
BuildRoot: %{_tmppath}/%{name}-%{version}-build
@@ -97,16 +96,15 @@
%patch5 -p1
%patch6 -p1
%patch7 -p1
+%patch13 -p1
%patch8 -p1
-%patch14 -p1
%patch9 -p1
%patch10 -p1
%patch11 -p1
%patch12 -p1
-%patch13 -p1
+%patch14 -p1
%patch15 -p1
%patch16 -p1
-%patch17 -p1
cp %SOURCE7 icons
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/gnome-panel-02-fish-applet.diff Fri Oct 20 15:31:04 2006 +0000
@@ -0,0 +1,77 @@
+diff -urNp gnome-panel-2.12.1/applets/Makefile.am gnome-panel-2.12.1-hacked/applets/Makefile.am
+--- gnome-panel-2.12.1/applets/Makefile.am 2003-03-07 13:43:19.000000000 +1300
++++ gnome-panel-2.12.1-hacked/applets/Makefile.am 2005-10-28 13:08:39.637882000 +1300
+@@ -1,6 +1,5 @@
+ SUBDIRS = \
+ clock \
+- fish \
+ notification_area \
+ wncklet
+
+--- gnome-panel-2.13.4/configure.in.orig Mon Jan 16 13:35:04 2006
++++ gnome-panel-2.13.4/configure.in Mon Jan 16 13:37:39 2006
+@@ -207,7 +207,6 @@
+ po/Makefile.in
+ applets/Makefile
+ applets/clock/Makefile
+-applets/fish/Makefile
+ applets/notification_area/Makefile
+ applets/wncklet/Makefile
+ doc/Makefile
+@@ -275,26 +275,20 @@
+ doc/reference/panel-applet/Makefile
+ help/Makefile
+ help/clock/Makefile
+-help/fish/Makefile
+ help/window-list/Makefile
+ help/workspace-switcher/Makefile
+ help/ja/Makefile
+-help/ja/fish/Makefile
+ help/ja/window-list/Makefile
+ help/ja/workspace-switcher/Makefile
+ help/de/Makefile
+-help/de/fish/Makefile
+ help/de/window-list/Makefile
+ help/de/workspace-switcher/Makefile
+ help/ko/Makefile
+-help/ko/fish/Makefile
+ help/ko/window-list/Makefile
+ help/ko/workspace-switcher/Makefile
+ help/zh_CN/Makefile
+-help/zh_CN/fish/Makefile
+ help/zh_CN/workspace-switcher/Makefile
+ help/zh_TW/Makefile
+-help/zh_TW/fish/Makefile
+ help/zh_TW/window-list/Makefile
+ help/zh_TW/workspace-switcher/Makefile
+ man/Makefile
+--- gnome-panel-2.13.4/help/Makefile.am.orig Mon Jan 16 13:44:56 2006
++++ gnome-panel-2.13.4/help/Makefile.am Mon Jan 16 13:45:02 2006
+@@ -1 +1 @@
+-SUBDIRS = clock fish window-list workspace-switcher ja de ko zh_CN zh_TW
++SUBDIRS = clock window-list workspace-switcher ja de ko zh_CN zh_TW
+--- gnome-panel-2.13.4/help/ja/Makefile.am.orig Mon Jan 16 13:38:28 2006
++++ gnome-panel-2.13.4/help/ja/Makefile.am Mon Jan 16 13:38:32 2006
+@@ -1 +1 @@
+-SUBDIRS = fish window-list workspace-switcher
++SUBDIRS = window-list workspace-switcher
+--- gnome-panel-2.13.4/help/de/Makefile.am.orig Mon Jan 16 13:37:55 2006
++++ gnome-panel-2.13.4/help/de/Makefile.am Mon Jan 16 13:38:15 2006
+@@ -1 +1 @@
+-SUBDIRS = fish window-list workspace-switcher
++SUBDIRS = window-list workspace-switcher
+--- gnome-panel-2.13.4/help/ko/Makefile.am.orig Mon Jan 16 13:38:37 2006
++++ gnome-panel-2.13.4/help/ko/Makefile.am Mon Jan 16 13:38:39 2006
+@@ -1 +1 @@
+-SUBDIRS = fish window-list workspace-switcher
++SUBDIRS = window-list workspace-switcher
+--- gnome-panel-2.15.9/help/zh_CN/Makefile.am.orig 2006-08-22 16:29:43.063135000 +0100
++++ gnome-panel-2.15.9/help/zh_CN/Makefile.am 2006-08-22 16:29:47.265224000 +0100
+@@ -1 +1 @@
+-SUBDIRS = fish workspace-switcher
++SUBDIRS = workspace-switcher
+--- gnome-panel-2.15.9/help/zh_TW/Makefile.am.orig 2006-08-22 16:28:55.202473000 +0100
++++ gnome-panel-2.15.9/help/zh_TW/Makefile.am 2006-08-22 16:29:00.300120000 +0100
+@@ -1 +1 @@
+-SUBDIRS = fish window-list workspace-switcher
++SUBDIRS = window-list workspace-switcher
--- a/patches/gnome-panel-02-workspace-switcher.diff Fri Oct 20 15:24:25 2006 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
---- gnome-panel-2.16.1.old/libpanel-applet/panel-applet.c 2006-10-19 17:05:32.211022000 +0100
-+++ gnome-panel-2.16.1/libpanel-applet/panel-applet.c 2006-10-19 17:10:01.081891000 +0100
-@@ -116,6 +116,8 @@
-
- static void panel_applet_handle_background (PanelApplet *applet);
- static void panel_applet_setup (PanelApplet *applet);
-+static void panel_applet_set_preferences_key (PanelApplet *applet,
-+ gboolean set);
-
- static void
- panel_applet_associate_schemas_in_dir (GConfClient *client,
-@@ -216,6 +218,7 @@
- schema_dir, our_error->message);
- g_error_free (our_error);
- }
-+ panel_applet_set_preferences_key (applet, TRUE);
- }
-
- char *
-@@ -231,11 +234,16 @@
-
- static void
- panel_applet_set_preferences_key (PanelApplet *applet,
-- const char *prefs_key)
-+ gboolean set)
- {
- g_return_if_fail (PANEL_IS_APPLET (applet));
-
-- if (applet->priv->prefs_key) {
-+ if (set) {
-+ gconf_client_add_dir (applet->priv->client,
-+ applet->priv->prefs_key,
-+ GCONF_CLIENT_PRELOAD_RECURSIVE,
-+ NULL);
-+ } else if (applet->priv->prefs_key) {
- gconf_client_remove_dir (applet->priv->client,
- applet->priv->prefs_key,
- NULL);
-@@ -243,15 +251,6 @@
- g_free (applet->priv->prefs_key);
- applet->priv->prefs_key = NULL;
- }
--
-- if (prefs_key) {
-- applet->priv->prefs_key = g_strdup (prefs_key);
--
-- gconf_client_add_dir (applet->priv->client,
-- applet->priv->prefs_key,
-- GCONF_CLIENT_PRELOAD_RECURSIVE,
-- NULL);
-- }
- }
-
- PanelAppletFlags
-@@ -540,7 +539,7 @@
- {
- PanelApplet *applet = PANEL_APPLET (object);
-
-- panel_applet_set_preferences_key (applet, NULL);
-+ panel_applet_set_preferences_key (applet, FALSE);
-
- if (applet->priv->client)
- g_object_unref (applet->priv->client);
-@@ -1402,7 +1401,7 @@
- continue;
-
- if (!strcmp (option->key, "prefs_key") && !applet->priv->prefs_key)
-- panel_applet_set_preferences_key (applet, option->value);
-+ applet->priv->prefs_key = g_strdup (option->value);
-
- else if (!strcmp (option->key, "background"))
- bonobo_pbclient_set_string (BONOBO_OBJREF (applet->priv->prop_sack),
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/gnome-panel-03-concurrent-login.diff Fri Oct 20 15:31:04 2006 +0000
@@ -0,0 +1,71 @@
+--- gnome-panel-2.6.1/gnome-panel/panel-gconf.c 2004-04-02 18:05:41.000000000 +0100
++++ gnome-panel-2.6.1-new/gnome-panel/panel-gconf.c 2004-10-08 11:17:41.343758872 +0100
+@@ -104,13 +104,13 @@ panel_gconf_key_type_to_id_list (PanelGC
+
+ switch (type) {
+ case PANEL_GCONF_TOPLEVELS:
+- retval = "toplevel_id_list";
++ retval = "toplevel_id_list_jds";
+ break;
+ case PANEL_GCONF_APPLETS:
+- retval = "applet_id_list";
++ retval = "applet_id_list_jds";
+ break;
+ case PANEL_GCONF_OBJECTS:
+- retval = "object_id_list";
++ retval = "object_id_list_jds";
+ break;
+ default:
+ retval = NULL;
+--- gnome-panel-2.6.1/gnome-panel/panel-profile.c 2004-04-02 18:05:41.000000000 +0100
++++ gnome-panel-2.6.1-new/gnome-panel/panel-profile.c 2004-10-08 11:19:29.073381480 +0100
+@@ -2365,8 +2365,14 @@ panel_profile_load (void)
+
+ panel_compatibility_maybe_copy_old_config (client);
+
++ /* Commenting this out till we figure out a clean way to migrate
++ objects of previous version of a release to the newer version
++ along with the objects that we intend to add in the newer version
++
+ panel_compatibility_migrate_panel_id_list (client);
+
++ */
++
+ gconf_client_add_dir (client, PANEL_CONFIG_DIR "/general", GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
+
+ panel_profile_load_list (client,
+--- gnome-panel-2.6.1/gnome-panel/panel-default-setup.entries 2004-10-07 19:02:01.000000000 +0100
++++ gnome-panel-2.6.1-new/gnome-panel/panel-default-setup.entries 2004-10-08 11:17:17.548376320 +0100
+@@ -5,8 +5,8 @@
+ <!-- List of toplevels -->
+
+ <entry>
+- <key>general/toplevel_id_list</key>
+- <schema_key>/schemas/apps/panel/general/toplevel_id_list</schema_key>
++ <key>general/toplevel_id_list_jds</key>
++ <schema_key>/schemas/apps/panel/general/toplevel_id_list_jds</schema_key>
+ <value>
+ <list type="string">
+ <value>
+@@ -19,8 +19,8 @@
+ <!-- List of objects -->
+
+ <entry>
+- <key>general/object_id_list</key>
+- <schema_key>/schemas/apps/panel/general/object_id_list</schema_key>
++ <key>general/object_id_list_jds</key>
++ <schema_key>/schemas/apps/panel/general/object_id_list_jds</schema_key>
+ <value>
+ <list type="string">
+ <value>
+@@ -33,8 +33,8 @@
+ <!-- List of applets -->
+
+ <entry>
+- <key>general/applet_id_list</key>
+- <schema_key>/schemas/apps/panel/general/applet_id_list</schema_key>
++ <key>general/applet_id_list_jds</key>
++ <schema_key>/schemas/apps/panel/general/applet_id_list_jds</schema_key>
+ <value>
+ <list type="string">
+ <value>
--- a/patches/gnome-panel-03-fish-applet.diff Fri Oct 20 15:24:25 2006 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,77 +0,0 @@
-diff -urNp gnome-panel-2.12.1/applets/Makefile.am gnome-panel-2.12.1-hacked/applets/Makefile.am
---- gnome-panel-2.12.1/applets/Makefile.am 2003-03-07 13:43:19.000000000 +1300
-+++ gnome-panel-2.12.1-hacked/applets/Makefile.am 2005-10-28 13:08:39.637882000 +1300
-@@ -1,6 +1,5 @@
- SUBDIRS = \
- clock \
-- fish \
- notification_area \
- wncklet
-
---- gnome-panel-2.13.4/configure.in.orig Mon Jan 16 13:35:04 2006
-+++ gnome-panel-2.13.4/configure.in Mon Jan 16 13:37:39 2006
-@@ -207,7 +207,6 @@
- po/Makefile.in
- applets/Makefile
- applets/clock/Makefile
--applets/fish/Makefile
- applets/notification_area/Makefile
- applets/wncklet/Makefile
- doc/Makefile
-@@ -275,26 +275,20 @@
- doc/reference/panel-applet/Makefile
- help/Makefile
- help/clock/Makefile
--help/fish/Makefile
- help/window-list/Makefile
- help/workspace-switcher/Makefile
- help/ja/Makefile
--help/ja/fish/Makefile
- help/ja/window-list/Makefile
- help/ja/workspace-switcher/Makefile
- help/de/Makefile
--help/de/fish/Makefile
- help/de/window-list/Makefile
- help/de/workspace-switcher/Makefile
- help/ko/Makefile
--help/ko/fish/Makefile
- help/ko/window-list/Makefile
- help/ko/workspace-switcher/Makefile
- help/zh_CN/Makefile
--help/zh_CN/fish/Makefile
- help/zh_CN/workspace-switcher/Makefile
- help/zh_TW/Makefile
--help/zh_TW/fish/Makefile
- help/zh_TW/window-list/Makefile
- help/zh_TW/workspace-switcher/Makefile
- man/Makefile
---- gnome-panel-2.13.4/help/Makefile.am.orig Mon Jan 16 13:44:56 2006
-+++ gnome-panel-2.13.4/help/Makefile.am Mon Jan 16 13:45:02 2006
-@@ -1 +1 @@
--SUBDIRS = clock fish window-list workspace-switcher ja de ko zh_CN zh_TW
-+SUBDIRS = clock window-list workspace-switcher ja de ko zh_CN zh_TW
---- gnome-panel-2.13.4/help/ja/Makefile.am.orig Mon Jan 16 13:38:28 2006
-+++ gnome-panel-2.13.4/help/ja/Makefile.am Mon Jan 16 13:38:32 2006
-@@ -1 +1 @@
--SUBDIRS = fish window-list workspace-switcher
-+SUBDIRS = window-list workspace-switcher
---- gnome-panel-2.13.4/help/de/Makefile.am.orig Mon Jan 16 13:37:55 2006
-+++ gnome-panel-2.13.4/help/de/Makefile.am Mon Jan 16 13:38:15 2006
-@@ -1 +1 @@
--SUBDIRS = fish window-list workspace-switcher
-+SUBDIRS = window-list workspace-switcher
---- gnome-panel-2.13.4/help/ko/Makefile.am.orig Mon Jan 16 13:38:37 2006
-+++ gnome-panel-2.13.4/help/ko/Makefile.am Mon Jan 16 13:38:39 2006
-@@ -1 +1 @@
--SUBDIRS = fish window-list workspace-switcher
-+SUBDIRS = window-list workspace-switcher
---- gnome-panel-2.15.9/help/zh_CN/Makefile.am.orig 2006-08-22 16:29:43.063135000 +0100
-+++ gnome-panel-2.15.9/help/zh_CN/Makefile.am 2006-08-22 16:29:47.265224000 +0100
-@@ -1 +1 @@
--SUBDIRS = fish workspace-switcher
-+SUBDIRS = workspace-switcher
---- gnome-panel-2.15.9/help/zh_TW/Makefile.am.orig 2006-08-22 16:28:55.202473000 +0100
-+++ gnome-panel-2.15.9/help/zh_TW/Makefile.am 2006-08-22 16:29:00.300120000 +0100
-@@ -1 +1 @@
--SUBDIRS = fish window-list workspace-switcher
-+SUBDIRS = window-list workspace-switcher
--- a/patches/gnome-panel-04-concurrent-login.diff Fri Oct 20 15:24:25 2006 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
---- gnome-panel-2.6.1/gnome-panel/panel-gconf.c 2004-04-02 18:05:41.000000000 +0100
-+++ gnome-panel-2.6.1-new/gnome-panel/panel-gconf.c 2004-10-08 11:17:41.343758872 +0100
-@@ -104,13 +104,13 @@ panel_gconf_key_type_to_id_list (PanelGC
-
- switch (type) {
- case PANEL_GCONF_TOPLEVELS:
-- retval = "toplevel_id_list";
-+ retval = "toplevel_id_list_jds";
- break;
- case PANEL_GCONF_APPLETS:
-- retval = "applet_id_list";
-+ retval = "applet_id_list_jds";
- break;
- case PANEL_GCONF_OBJECTS:
-- retval = "object_id_list";
-+ retval = "object_id_list_jds";
- break;
- default:
- retval = NULL;
---- gnome-panel-2.6.1/gnome-panel/panel-profile.c 2004-04-02 18:05:41.000000000 +0100
-+++ gnome-panel-2.6.1-new/gnome-panel/panel-profile.c 2004-10-08 11:19:29.073381480 +0100
-@@ -2365,8 +2365,14 @@ panel_profile_load (void)
-
- panel_compatibility_maybe_copy_old_config (client);
-
-+ /* Commenting this out till we figure out a clean way to migrate
-+ objects of previous version of a release to the newer version
-+ along with the objects that we intend to add in the newer version
-+
- panel_compatibility_migrate_panel_id_list (client);
-
-+ */
-+
- gconf_client_add_dir (client, PANEL_CONFIG_DIR "/general", GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
-
- panel_profile_load_list (client,
---- gnome-panel-2.6.1/gnome-panel/panel-default-setup.entries 2004-10-07 19:02:01.000000000 +0100
-+++ gnome-panel-2.6.1-new/gnome-panel/panel-default-setup.entries 2004-10-08 11:17:17.548376320 +0100
-@@ -5,8 +5,8 @@
- <!-- List of toplevels -->
-
- <entry>
-- <key>general/toplevel_id_list</key>
-- <schema_key>/schemas/apps/panel/general/toplevel_id_list</schema_key>
-+ <key>general/toplevel_id_list_jds</key>
-+ <schema_key>/schemas/apps/panel/general/toplevel_id_list_jds</schema_key>
- <value>
- <list type="string">
- <value>
-@@ -19,8 +19,8 @@
- <!-- List of objects -->
-
- <entry>
-- <key>general/object_id_list</key>
-- <schema_key>/schemas/apps/panel/general/object_id_list</schema_key>
-+ <key>general/object_id_list_jds</key>
-+ <schema_key>/schemas/apps/panel/general/object_id_list_jds</schema_key>
- <value>
- <list type="string">
- <value>
-@@ -33,8 +33,8 @@
- <!-- List of applets -->
-
- <entry>
-- <key>general/applet_id_list</key>
-- <schema_key>/schemas/apps/panel/general/applet_id_list</schema_key>
-+ <key>general/applet_id_list_jds</key>
-+ <schema_key>/schemas/apps/panel/general/applet_id_list_jds</schema_key>
- <value>
- <list type="string">
- <value>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/gnome-panel-04-panel-applet-session-never-restart.diff Fri Oct 20 15:31:04 2006 +0000
@@ -0,0 +1,53 @@
+--- gnome-panel-2.16.1.old/libpanel-applet/panel-applet.h 2006-10-19 17:12:24.278934000 +0100
++++ gnome-panel-2.16.1/libpanel-applet/panel-applet.h 2006-10-19 17:17:47.032180000 +0100
+@@ -183,6 +183,18 @@
+ * + optional : PREFIX, SYSCONFDIR, DATADIR and LIBDIR.
+ */
+
++static void panel_applet_session_never_restart (void);
++
++void panel_applet_session_never_restart()
++{
++ GnomeClient *client;
++ client = gnome_master_client ();
++ gnome_client_set_restart_style (client, GNOME_RESTART_NEVER);
++ gnome_client_connect (client);
++ gnome_client_flush (client);
++}
++
++#define PANEL_APPLET_SESSION_NEVER_RESTART panel_applet_session_never_restart()
+ #if !defined(ENABLE_NLS)
+ #if defined(PREFIX) && defined(SYSCONFDIR) && defined(DATADIR) && defined(LIBDIR)
+ #define PANEL_APPLET_BONOBO_FACTORY(iid, type, name, version, callback, data) \
+@@ -199,6 +211,7 @@
+ GNOME_CLIENT_PARAM_SM_CONNECT, FALSE, \
+ GNOME_PROGRAM_STANDARD_PROPERTIES, \
+ NULL); \
++ PANEL_APPLET_SESSION_NEVER_RESTART; \
+ retval = panel_applet_factory_main (iid, type, callback, data); \
+ g_object_unref (program); \
+ return retval; \
+@@ -214,6 +227,7 @@
+ argc, argv, \
+ GNOME_CLIENT_PARAM_SM_CONNECT, FALSE, \
+ GNOME_PARAM_NONE); \
++ PANEL_APPLET_SESSION_NEVER_RESTART; \
+ retval = panel_applet_factory_main (iid, type, callback, data); \
+ g_object_unref (program); \
+ return retval; \
+@@ -239,6 +253,7 @@
+ GNOME_CLIENT_PARAM_SM_CONNECT, FALSE, \
+ GNOME_PROGRAM_STANDARD_PROPERTIES, \
+ NULL); \
++ PANEL_APPLET_SESSION_NEVER_RESTART; \
+ retval = panel_applet_factory_main (iid, type, callback, data); \
+ g_object_unref (program); \
+ return retval; \
+@@ -260,6 +275,7 @@
+ GNOME_PARAM_GOPTION_CONTEXT, context, \
+ GNOME_CLIENT_PARAM_SM_CONNECT, FALSE, \
+ GNOME_PARAM_NONE); \
++ PANEL_APPLET_SESSION_NEVER_RESTART; \
+ retval = panel_applet_factory_main (iid, type, callback, data); \
+ g_object_unref (program); \
+ return retval; \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/gnome-panel-05-notificationarea-tooltip.diff Fri Oct 20 15:31:04 2006 +0000
@@ -0,0 +1,51 @@
+--- gnome-panel-2.16.1.old/applets/notification_area/main.c 2006-10-19 17:33:13.535025000 +0100
++++ gnome-panel-2.16.1/applets/notification_area/main.c 2006-10-19 17:44:43.544988000 +0100
+@@ -53,7 +53,9 @@
+ GtkWidget *box;
+ GtkWidget *about_dialog;
+ GtkWidget *frame;
++ GtkTooltips *tooltips;
+
++ GSList *icons;
+ GtkOrientation orientation;
+ } SystemTray;
+
+@@ -82,6 +84,18 @@
+ static void icon_tip_show_next (IconTip *icontip);
+
+ static void
++set_tooltip (SystemTray *tray)
++{
++ tray->tooltips = gtk_tooltips_new ();
++ g_object_ref (tray->tooltips);
++ gtk_object_sink (GTK_OBJECT (tray->tooltips));
++ g_object_set_data_full (G_OBJECT (tray->tooltips), "tooltips", tray->tooltips,
++ (GDestroyNotify) g_object_unref);
++ gtk_tooltips_set_tip (tray->tooltips, GTK_WIDGET (tray->applet),
++ _("Area where notification icons appear"), NULL);
++}
++
++static void
+ help_cb (BonoboUIComponent *uic,
+ SystemTray *tray,
+ const gchar *verbname)
+@@ -213,6 +227,10 @@
+ g_hash_table_insert (tray->trays_screen->icon_table, icon, tray);
+
+ gtk_box_pack_end (GTK_BOX (tray->box), icon, FALSE, FALSE, 0);
++
++ tray->icons = g_slist_append (tray->icons, icon);
++
++ gtk_tooltips_disable (tray->tooltips);
+
+ gtk_widget_show (icon);
+ force_redraw (tray);
+@@ -692,6 +710,8 @@
+ panel_applet_set_background_widget (tray->applet, GTK_WIDGET (tray->applet));
+
+ update_size_and_orientation (tray);
++
++ set_tooltip (tray);
+
+ gtk_container_add (GTK_CONTAINER (tray->applet), tray->frame);
+
--- a/patches/gnome-panel-05-panel-applet-session-never-restart.diff Fri Oct 20 15:24:25 2006 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
---- gnome-panel-2.16.1.old/libpanel-applet/panel-applet.h 2006-10-19 17:12:24.278934000 +0100
-+++ gnome-panel-2.16.1/libpanel-applet/panel-applet.h 2006-10-19 17:17:47.032180000 +0100
-@@ -183,6 +183,18 @@
- * + optional : PREFIX, SYSCONFDIR, DATADIR and LIBDIR.
- */
-
-+static void panel_applet_session_never_restart (void);
-+
-+void panel_applet_session_never_restart()
-+{
-+ GnomeClient *client;
-+ client = gnome_master_client ();
-+ gnome_client_set_restart_style (client, GNOME_RESTART_NEVER);
-+ gnome_client_connect (client);
-+ gnome_client_flush (client);
-+}
-+
-+#define PANEL_APPLET_SESSION_NEVER_RESTART panel_applet_session_never_restart()
- #if !defined(ENABLE_NLS)
- #if defined(PREFIX) && defined(SYSCONFDIR) && defined(DATADIR) && defined(LIBDIR)
- #define PANEL_APPLET_BONOBO_FACTORY(iid, type, name, version, callback, data) \
-@@ -199,6 +211,7 @@
- GNOME_CLIENT_PARAM_SM_CONNECT, FALSE, \
- GNOME_PROGRAM_STANDARD_PROPERTIES, \
- NULL); \
-+ PANEL_APPLET_SESSION_NEVER_RESTART; \
- retval = panel_applet_factory_main (iid, type, callback, data); \
- g_object_unref (program); \
- return retval; \
-@@ -214,6 +227,7 @@
- argc, argv, \
- GNOME_CLIENT_PARAM_SM_CONNECT, FALSE, \
- GNOME_PARAM_NONE); \
-+ PANEL_APPLET_SESSION_NEVER_RESTART; \
- retval = panel_applet_factory_main (iid, type, callback, data); \
- g_object_unref (program); \
- return retval; \
-@@ -239,6 +253,7 @@
- GNOME_CLIENT_PARAM_SM_CONNECT, FALSE, \
- GNOME_PROGRAM_STANDARD_PROPERTIES, \
- NULL); \
-+ PANEL_APPLET_SESSION_NEVER_RESTART; \
- retval = panel_applet_factory_main (iid, type, callback, data); \
- g_object_unref (program); \
- return retval; \
-@@ -260,6 +275,7 @@
- GNOME_PARAM_GOPTION_CONTEXT, context, \
- GNOME_CLIENT_PARAM_SM_CONNECT, FALSE, \
- GNOME_PARAM_NONE); \
-+ PANEL_APPLET_SESSION_NEVER_RESTART; \
- retval = panel_applet_factory_main (iid, type, callback, data); \
- g_object_unref (program); \
- return retval; \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/gnome-panel-06-input-method-filter-keypress.diff Fri Oct 20 15:31:04 2006 +0000
@@ -0,0 +1,15 @@
+--- gnome-panel-2.16.1.old/gnome-panel/panel-run-dialog.c 2006-10-19 17:47:31.408880000 +0100
++++ gnome-panel-2.16.1/gnome-panel/panel-run-dialog.c 2006-10-19 17:49:37.047394000 +0100
+@@ -1436,6 +1436,12 @@
+ char *temp;
+ int pos, tmp;
+
++ /* commit the string when IM is enabled */
++ if (GTK_ENTRY (entry)->editable && event->type == GDK_KEY_PRESS && event->length > 0) {
++ if (gtk_im_context_filter_keypress (GTK_ENTRY (entry)->im_context, event))
++ return TRUE;
++ }
++
+ if (event->type != GDK_KEY_PRESS)
+ return FALSE;
+
--- a/patches/gnome-panel-06-notificationarea-tooltip.diff Fri Oct 20 15:24:25 2006 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
---- gnome-panel-2.16.1.old/applets/notification_area/main.c 2006-10-19 17:33:13.535025000 +0100
-+++ gnome-panel-2.16.1/applets/notification_area/main.c 2006-10-19 17:44:43.544988000 +0100
-@@ -53,7 +53,9 @@
- GtkWidget *box;
- GtkWidget *about_dialog;
- GtkWidget *frame;
-+ GtkTooltips *tooltips;
-
-+ GSList *icons;
- GtkOrientation orientation;
- } SystemTray;
-
-@@ -82,6 +84,18 @@
- static void icon_tip_show_next (IconTip *icontip);
-
- static void
-+set_tooltip (SystemTray *tray)
-+{
-+ tray->tooltips = gtk_tooltips_new ();
-+ g_object_ref (tray->tooltips);
-+ gtk_object_sink (GTK_OBJECT (tray->tooltips));
-+ g_object_set_data_full (G_OBJECT (tray->tooltips), "tooltips", tray->tooltips,
-+ (GDestroyNotify) g_object_unref);
-+ gtk_tooltips_set_tip (tray->tooltips, GTK_WIDGET (tray->applet),
-+ _("Area where notification icons appear"), NULL);
-+}
-+
-+static void
- help_cb (BonoboUIComponent *uic,
- SystemTray *tray,
- const gchar *verbname)
-@@ -213,6 +227,10 @@
- g_hash_table_insert (tray->trays_screen->icon_table, icon, tray);
-
- gtk_box_pack_end (GTK_BOX (tray->box), icon, FALSE, FALSE, 0);
-+
-+ tray->icons = g_slist_append (tray->icons, icon);
-+
-+ gtk_tooltips_disable (tray->tooltips);
-
- gtk_widget_show (icon);
- force_redraw (tray);
-@@ -692,6 +710,8 @@
- panel_applet_set_background_widget (tray->applet, GTK_WIDGET (tray->applet));
-
- update_size_and_orientation (tray);
-+
-+ set_tooltip (tray);
-
- gtk_container_add (GTK_CONTAINER (tray->applet), tray->frame);
-
--- a/patches/gnome-panel-07-input-method-filter-keypress.diff Fri Oct 20 15:24:25 2006 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,15 +0,0 @@
---- gnome-panel-2.16.1.old/gnome-panel/panel-run-dialog.c 2006-10-19 17:47:31.408880000 +0100
-+++ gnome-panel-2.16.1/gnome-panel/panel-run-dialog.c 2006-10-19 17:49:37.047394000 +0100
-@@ -1436,6 +1436,12 @@
- char *temp;
- int pos, tmp;
-
-+ /* commit the string when IM is enabled */
-+ if (GTK_ENTRY (entry)->editable && event->type == GDK_KEY_PRESS && event->length > 0) {
-+ if (gtk_im_context_filter_keypress (GTK_ENTRY (entry)->im_context, event))
-+ return TRUE;
-+ }
-+
- if (event->type != GDK_KEY_PRESS)
- return FALSE;
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/gnome-panel-07-restrict-app-launching.diff Fri Oct 20 15:31:04 2006 +0000
@@ -0,0 +1,998 @@
+--- gnome-panel-2.15.91.old/gnome-panel/Makefile.am 2006-08-09 15:43:31.107934000 +0100
++++ gnome-panel-2.15.91/gnome-panel/Makefile.am 2006-08-09 15:58:00.483203000 +0100
+@@ -167,6 +167,8 @@
+ panel-ditem-editor.c \
+ panel-marshal.c \
+ panel-util.c \
++ panel-lockdown.c \
++ panel-gconf.c \
+ xstuff.c
+
+ gnome_desktop_item_edit_LDFLAGS = -export-dynamic
+--- gnome-panel-2.15.91.old/gnome-panel/panel-util.c 2006-08-09 15:43:31.117319000 +0100
++++ gnome-panel-2.15.91/gnome-panel/panel-util.c 2006-08-09 16:00:29.664793000 +0100
+@@ -34,6 +34,7 @@
+ #include "xstuff.h"
+ #include "panel-globals.h"
+ #include "launcher.h"
++#include "panel-lockdown.h"
+
+ static int
+ panel_ditem_launch (GnomeDesktopItem *item,
+@@ -705,6 +706,9 @@
+ char *command = NULL;
+ gboolean use_gscreensaver = FALSE;
+
++ if (panel_lockdown_get_disable_lock_screen () )
++ return NULL;
++
+ if (panel_is_program_in_path ("gnome-screensaver-command")
+ && panel_is_program_in_path ("gnome-screensaver-preferences"))
+ use_gscreensaver = TRUE;
+--- gnome-panel-2.15.91.old/gnome-panel/menu.c 2006-08-09 15:43:31.124010000 +0100
++++ gnome-panel-2.15.91/gnome-panel/menu.c 2006-08-09 17:39:54.146347000 +0100
+@@ -72,7 +72,8 @@
+ static GSList *image_menu_items = NULL;
+
+ static GtkWidget *populate_menu_from_directory (GtkWidget *menu,
+- GMenuTreeDirectory *directory);
++ GMenuTreeDirectory *directory,
++ gboolean *is_hidden);
+
+ static void panel_load_menu_image_deferred (GtkWidget *image_menu_item,
+ GtkIconSize icon_size,
+@@ -1308,7 +1309,8 @@
+ }
+
+ static void
+-submenu_to_display (GtkWidget *menu)
++submenu_to_display (GtkWidget *menu,
++ gboolean *is_hidden)
+ {
+ GMenuTree *tree;
+ GMenuTreeDirectory *directory;
+@@ -1340,18 +1342,27 @@
+ (GDestroyNotify) gmenu_tree_item_unref);
+ }
+
+- if (directory)
+- populate_menu_from_directory (menu, directory);
++ if (directory) {
++ /* It's possible that is_hidden is NULL if we end up here from the show
++ signal, which could only happen for the top level menu. */
++ gboolean local_is_hidden = FALSE;
++
++ populate_menu_from_directory (menu, directory, &local_is_hidden);
++ if (is_hidden != NULL) {
++ *is_hidden = local_is_hidden;
++ }
++ }
+ }
+
+ static gboolean
+ submenu_to_display_in_idle (gpointer data)
+ {
+ GtkWidget *menu = GTK_WIDGET (data);
++ gboolean is_hidden = FALSE;
+
+ g_object_set_data (G_OBJECT (menu), "panel-menu-idle-id", NULL);
+
+- submenu_to_display (menu);
++ submenu_to_display (menu, &is_hidden);
+
+ return FALSE;
+ }
+@@ -1437,28 +1448,41 @@
+ static void
+ create_submenu (GtkWidget *menu,
+ GMenuTreeDirectory *directory,
+- GMenuTreeDirectory *alias_directory)
++ GMenuTreeDirectory *alias_directory,
++ gboolean *is_hidden)
+ {
+ GtkWidget *menuitem;
+ GtkWidget *submenu;
+
++ submenu = create_fake_menu (directory);
++ if (panel_lockdown_get_restrict_application_launching ()) {
++ submenu_to_display (submenu, is_hidden);
++ }
++ else {
++ *is_hidden = FALSE;
++ }
++
+ if (alias_directory)
+ menuitem = create_submenu_entry (menu, alias_directory);
+ else
+ menuitem = create_submenu_entry (menu, directory);
+
+- submenu = create_fake_menu (directory);
+-
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
++
++ if (*is_hidden) {
++ gtk_widget_hide (menuitem);
++ }
+ }
+
+ static void
+ create_header (GtkWidget *menu,
+- GMenuTreeHeader *header)
++ GMenuTreeHeader *header,
++ gboolean *is_hidden)
+ {
+ GMenuTreeDirectory *directory;
+ GtkWidget *menuitem;
+
++ *is_hidden = FALSE;
+ directory = gmenu_tree_header_get_directory (header);
+ menuitem = create_submenu_entry (menu, directory);
+ gmenu_tree_item_unref (directory);
+@@ -1475,10 +1499,12 @@
+ static void
+ create_menuitem (GtkWidget *menu,
+ GMenuTreeEntry *entry,
+- GMenuTreeDirectory *alias_directory)
++ GMenuTreeDirectory *alias_directory,
++ gboolean *is_hidden)
+ {
+ GtkWidget *menuitem;
+
++ *is_hidden = FALSE;
+ menuitem = gtk_image_menu_item_new ();
+
+ g_object_set_data_full (G_OBJECT (menuitem),
+@@ -1508,6 +1534,11 @@
+ gmenu_tree_entry_get_name (entry),
+ TRUE);
+
++ if (entry != NULL && !panel_lockdown_is_allowed_menu_entry (entry)) {
++ gtk_widget_hide (menuitem);
++ *is_hidden = TRUE;
++ }
++
+ if ((alias_directory &&
+ gmenu_tree_directory_get_comment (alias_directory)) ||
+ (!alias_directory &&
+@@ -1551,7 +1582,8 @@
+
+ static void
+ create_menuitem_from_alias (GtkWidget *menu,
+- GMenuTreeAlias *alias)
++ GMenuTreeAlias *alias,
++ gboolean *is_hidden)
+ {
+ GMenuTreeItem *aliased_item;
+
+@@ -1561,13 +1593,15 @@
+ case GMENU_TREE_ITEM_DIRECTORY:
+ create_submenu (menu,
+ GMENU_TREE_DIRECTORY (aliased_item),
+- gmenu_tree_alias_get_directory (alias));
++ gmenu_tree_alias_get_directory (alias),
++ is_hidden);
+ break;
+
+ case GMENU_TREE_ITEM_ENTRY:
+ create_menuitem (menu,
+ GMENU_TREE_ENTRY (aliased_item),
+- gmenu_tree_alias_get_directory (alias));
++ gmenu_tree_alias_get_directory (alias),
++ is_hidden);
+ break;
+
+ default:
+@@ -1675,18 +1709,21 @@
+
+ static GtkWidget *
+ populate_menu_from_directory (GtkWidget *menu,
+- GMenuTreeDirectory *directory)
++ GMenuTreeDirectory *directory,
++ gboolean *is_hidden)
+ {
+ GSList *l;
+ GSList *items;
+ gboolean add_separator;
+
++ *is_hidden = TRUE;
+ add_separator = (GTK_MENU_SHELL (menu)->children != NULL);
+
+ items = gmenu_tree_directory_get_contents (directory);
+
+ for (l = items; l; l = l->next) {
+ GMenuTreeItem *item = l->data;
++ gboolean is_item_hidden = TRUE;
+
+ if (add_separator ||
+ gmenu_tree_item_get_type (item) == GMENU_TREE_ITEM_SEPARATOR) {
+@@ -1696,11 +1733,13 @@
+
+ switch (gmenu_tree_item_get_type (item)) {
+ case GMENU_TREE_ITEM_DIRECTORY:
+- create_submenu (menu, GMENU_TREE_DIRECTORY (item), NULL);
++ create_submenu (menu, GMENU_TREE_DIRECTORY (item), NULL,
++ &is_item_hidden);
+ break;
+
+ case GMENU_TREE_ITEM_ENTRY:
+- create_menuitem (menu, GMENU_TREE_ENTRY (item), NULL);
++ create_menuitem (menu, GMENU_TREE_ENTRY (item), NULL,
++ &is_item_hidden);
+ break;
+
+ case GMENU_TREE_ITEM_SEPARATOR :
+@@ -1708,11 +1747,13 @@
+ break;
+
+ case GMENU_TREE_ITEM_ALIAS:
+- create_menuitem_from_alias (menu, GMENU_TREE_ALIAS (item));
++ create_menuitem_from_alias (menu, GMENU_TREE_ALIAS (item),
++ &is_item_hidden);
+ break;
+
+ case GMENU_TREE_ITEM_HEADER:
+- create_header (menu, GMENU_TREE_HEADER (item));
++ create_header (menu, GMENU_TREE_HEADER (item),
++ &is_item_hidden);
+ break;
+
+ default:
+@@ -1720,6 +1761,9 @@
+ }
+
+ gmenu_tree_item_unref (item);
++ if (!is_item_hidden) {
++ *is_hidden = FALSE;
++ }
+ }
+
+ g_slist_free (items);
+--- gnome-panel-2.15.91.old/gnome-panel/panel-menu-bar.c 2006-08-09 15:43:31.127630000 +0100
++++ gnome-panel-2.15.91/gnome-panel/panel-menu-bar.c 2006-08-09 18:01:50.710691000 +0100
+@@ -168,6 +168,17 @@
+ "", NULL);
+ }
+
++static void
++panel_menubar_recreate_menus (PanelMenuBar *menubar)
++{
++ if (menubar->priv->applications_menu != NULL) {
++ while (GTK_MENU_SHELL (menubar->priv->applications_menu)->children) {
++ gtk_widget_destroy (GTK_MENU_SHELL (menubar->priv->applications_menu)->children->data) ;
++ }
++ menubar->priv->applications_menu = create_applications_menu ("applications.menu", NULL) ;
++ }
++}
++
+ static void
+ panel_menu_bar_instance_init (PanelMenuBar *menubar,
+ PanelMenuBarClass *klass)
+@@ -200,6 +211,7 @@
+ menubar->priv->desktop_item);
+
+ panel_menu_bar_setup_tooltip (menubar);
++ panel_lockdown_notify_add (G_CALLBACK (panel_menubar_recreate_menus), menubar);
+ }
+
+ static void
+--- gnome-panel-2.15.91.old/gnome-panel/panel-addto.c 2006-08-09 15:43:31.406993000 +0100
++++ gnome-panel-2.15.91/gnome-panel/panel-addto.c 2006-08-09 18:11:14.990889000 +0100
+@@ -558,9 +558,10 @@
+ dialog, NULL);
+ }
+
+-static void panel_addto_make_application_list (GSList **parent_list,
++static gint panel_addto_make_application_list (GSList **parent_list,
+ GMenuTreeDirectory *directory,
+ const char *filename);
++static void panel_addto_dialog_free_item_info (PanelAddtoItemInfo *item_info);
+
+ static void
+ panel_addto_prepend_directory (GSList **parent_list,
+@@ -568,6 +569,7 @@
+ const char *filename)
+ {
+ PanelAddtoAppList *data;
++ gint entries_added = 0;
+
+ data = g_new0 (PanelAddtoAppList, 1);
+
+@@ -587,9 +589,16 @@
+ * So the iid is built when we select the row.
+ */
+
+- *parent_list = g_slist_prepend (*parent_list, data);
+-
+- panel_addto_make_application_list (&data->children, directory, filename);
++ entries_added = panel_addto_make_application_list (&data->children, directory, filename);
++ if (entries_added > 0) {
++ /*Only prepend if there are entries */
++ *parent_list = g_slist_prepend (*parent_list, data);
++ }
++ else {
++ /* Free data as not being appended */
++ panel_addto_dialog_free_item_info (&data->item_info);
++ g_free (data);
++ }
+ }
+
+ static void
+@@ -611,12 +620,13 @@
+ *parent_list = g_slist_prepend (*parent_list, data);
+ }
+
+-static void
++static gint
+ panel_addto_prepend_alias (GSList **parent_list,
+ GMenuTreeAlias *alias,
+ const char *filename)
+ {
+ GMenuTreeItem *aliased_item;
++ gint entry = 0;
+
+ aliased_item = gmenu_tree_alias_get_item (alias);
+
+@@ -628,9 +638,12 @@
+ break;
+
+ case GMENU_TREE_ITEM_ENTRY:
+- panel_addto_prepend_entry (parent_list,
+- GMENU_TREE_ENTRY (aliased_item),
+- filename);
++ if (panel_lockdown_is_allowed_menu_entry (GMENU_TREE_ENTRY (aliased_item))) {
++ panel_addto_prepend_entry (parent_list,
++ GMENU_TREE_ENTRY (aliased_item),
++ filename);
++ entry = 1;
++ }
+ break;
+
+ default:
+@@ -638,15 +651,17 @@
+ }
+
+ gmenu_tree_item_unref (aliased_item);
++ return entry;
+ }
+
+-static void
++static gint
+ panel_addto_make_application_list (GSList **parent_list,
+ GMenuTreeDirectory *directory,
+ const char *filename)
+ {
+ GSList *items;
+ GSList *l;
++ gint number_entries = 0;
+
+ items = gmenu_tree_directory_get_contents (directory);
+
+@@ -657,11 +672,15 @@
+ break;
+
+ case GMENU_TREE_ITEM_ENTRY:
+- panel_addto_prepend_entry (parent_list, l->data, filename);
++ if (panel_lockdown_is_allowed_menu_entry (l->data)) {
++ panel_addto_prepend_entry (parent_list, l->data, filename);
++ number_entries = number_entries + 1;
++ }
+ break;
+
+ case GMENU_TREE_ITEM_ALIAS:
+- panel_addto_prepend_alias (parent_list, l->data, filename);
++ number_entries = number_entries +
++ panel_addto_prepend_alias (parent_list, l->data, filename);
+ break;
+
+ default:
+@@ -674,6 +693,8 @@
+ g_slist_free (items);
+
+ *parent_list = g_slist_reverse (*parent_list);
++
++ return number_entries;
+ }
+
+ static void
+--- gnome-panel-2.15.91.old/gnome-panel/panel-action-button.c 2006-08-09 15:43:31.127312000 +0100
++++ gnome-panel-2.15.91/gnome-panel/panel-action-button.c 2006-08-10 11:28:35.882566000 +0100
+@@ -178,8 +178,11 @@
+ static void
+ panel_action_run_program (GtkWidget *widget)
+ {
+- panel_run_dialog_present (gtk_widget_get_screen (widget),
+- gtk_get_current_event_time ());
++ if (!panel_lockdown_get_restrict_application_launching () &&
++ !panel_lockdown_get_disable_command_line ()) {
++ panel_run_dialog_present (gtk_widget_get_screen (widget),
++ gtk_get_current_event_time ());
++ }
+ }
+
+ /* Search For Files
+@@ -190,6 +193,11 @@
+ GdkScreen *screen;
+ GError *error = NULL;
+
++ /* LOCKDOWN FIXME ---- FIX PATH --- */
++ if (panel_lockdown_is_forbidden_command ("/usr/bin/gnome-search-tool")) {
++ return;
++ }
++
+ screen = gtk_widget_get_screen (widget);
+ panel_launch_desktop_file ("gnome-search-tool.desktop",
+ "gnome-search-tool",
+--- gnome-panel-2.15.91.old/gnome-panel/gnome-desktop-item-edit.c 2006-08-10 14:12:18.746542000 +0100
++++ gnome-panel-2.15.91/gnome-panel/gnome-desktop-item-edit.c 2006-08-10 14:12:12.298142000 +0100
+@@ -9,6 +9,7 @@
+
+ #include "panel-ditem-editor.h"
+ #include "panel-util.h"
++#include "panel-lockdown.h"
+
+ #include "nothing.cP"
+
+@@ -176,6 +177,8 @@
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+ textdomain (GETTEXT_PACKAGE);
+
++ panel_lockdown_init ();
++
+ context = g_option_context_new (_("- Edit .desktop files"));
+
+ g_option_context_add_main_entries (context, options, GETTEXT_PACKAGE);
+@@ -301,5 +304,7 @@
+
+ g_object_unref (program);
+
++ panel_lockdown_finalize ();
++
+ return 0;
+ }
+--- gnome-panel-2.15.91.old/gnome-panel/panel-lockdown.h 2006-08-10 17:07:04.897831000 +0100
++++ gnome-panel-2.15.91/gnome-panel/panel-lockdown.h 2006-08-10 17:05:45.569877000 +0100
+@@ -25,8 +25,11 @@
+ #ifndef __PANEL_LOCKDOWN_H__
+ #define __PANEL_LOCKDOWN_H__
+
++#include <libgnome/gnome-desktop-item.h>
+ #include <glib.h>
+ #include <glib-object.h>
++#include <gmenu-tree.h>
++#include "launcher.h"
+
+ G_BEGIN_DECLS
+
+@@ -38,14 +41,56 @@
+ gboolean panel_lockdown_get_disable_lock_screen (void);
+ gboolean panel_lockdown_get_disable_log_out (void);
+ gboolean panel_lockdown_get_disable_force_quit (void);
++gboolean panel_lockdown_get_restrict_application_launching (void);
++GSList *panel_lockdown_get_allowed_applications (void);
+
+ gboolean panel_lockdown_is_applet_disabled (const char *iid);
++gboolean panel_lockdown_is_allowed_application (const gchar *app);
+
+ void panel_lockdown_notify_add (GCallback callback_func,
+ gpointer user_data);
+ void panel_lockdown_notify_remove (GCallback callback_func,
+ gpointer user_data);
+
++gchar *panel_lockdown_get_stripped_exec (const gchar *full_exec);
++gchar *panel_lockdown_get_exec_from_ditem (GnomeDesktopItem *ditem);
++gboolean panel_lockdown_ditem_in_allowed_applications (GnomeDesktopItem *ditem);
++gboolean panel_lockdown_is_disabled_command_line (const gchar *term_cmd);
++
++/**
++ * Returns true if the ditem corresponds to an application whose use has been
++ * disallowed by the administrator (tests whether restrictions are in place
++ * and if the ditem matches the allowed applications list).
++ */
++gboolean panel_lockdown_is_forbidden_app (GnomeDesktopItem *ditem);
++/**
++ * Returns true if the ditem corresponds to either an application whose use
++ * has been disallowed by the administrator (same as previous function) or
++ * a shell when command line use has been restricted.
++ */
++gboolean panel_lockdown_is_forbidden_ditem (GnomeDesktopItem *ditem);
++/**
++ * Returns true if the command line corresponds to an application whose use
++ * has been disallowed by the administrator.
++ */
++gboolean panel_lockdown_is_forbidden_command (const gchar *command);
++
++/**
++ * Returns true if the menu entry corresponds to an application whose use
++ * has been allowed by the administrator.
++ */
++gboolean panel_lockdown_is_allowed_menu_entry (GMenuTreeEntry *entry);
++
++/**
++ * Returns true if the launcher application has been disallowed by the administrator.
++ */
++gboolean panel_lockdown_is_forbidden_launcher (Launcher *launcher);
++
++/**
++ * Returns true if the key_file application has been disallowed by the administrator.
++ */
++gboolean panel_lockdown_is_forbidden_key_file (GKeyFile *key_file);
++
+ G_END_DECLS
+
+ #endif /* __PANEL_LOCKDOWN_H__ */
+--- gnome-panel-2.15.91.old/gnome-panel/panel-lockdown.c 2006-08-10 17:28:30.033061000 +0100
++++ gnome-panel-2.15.91/gnome-panel/panel-lockdown.c 2006-08-10 17:27:59.592217000 +0100
+@@ -28,13 +28,16 @@
+
+ #include <string.h>
+ #include "panel-gconf.h"
++#include "panel-util.h"
+
+-#define N_LISTENERS 6
++#define N_LISTENERS 8
+
+ #define PANEL_GLOBAL_LOCKDOWN_DIR "/apps/panel/global"
+ #define DESKTOP_GNOME_LOCKDOWN_DIR "/desktop/gnome/lockdown"
+ #define PANEL_GLOBAL_LOCKED_DOWN_KEY PANEL_GLOBAL_LOCKDOWN_DIR "/locked_down"
+ #define DISABLE_COMMAND_LINE_KEY DESKTOP_GNOME_LOCKDOWN_DIR "/disable_command_line"
++#define RESTRICT_APPLICATION_LAUNCHING_KEY DESKTOP_GNOME_LOCKDOWN_DIR "/restrict_application_launching"
++#define ALLOWED_APPLICATIONS_KEY DESKTOP_GNOME_LOCKDOWN_DIR "/allowed_applications"
+ #define DISABLE_LOCK_SCREEN_KEY PANEL_GLOBAL_LOCKDOWN_DIR "/disable_lock_screen"
+ #define DISABLE_LOG_OUT_KEY PANEL_GLOBAL_LOCKDOWN_DIR "/disable_log_out"
+ #define DISABLE_FORCE_QUIT_KEY PANEL_GLOBAL_LOCKDOWN_DIR "/disable_force_quit"
+@@ -48,6 +51,9 @@
+ guint disable_lock_screen : 1;
+ guint disable_log_out : 1;
+ guint disable_force_quit : 1;
++ guint restrict_application_launching : 1;
++
++ GSList *allowed_applications;
+
+ GSList *disabled_applets;
+
+@@ -56,6 +62,12 @@
+ GSList *closures;
+ } PanelLockdown;
+
++static const gchar *command_line_execs[] = {
++ "/usr/bin/gnome-terminal",
++ "/usr/bin/xterm"
++};
++#define NUMBER_COMMAND_LINE_EXECS 2
++
+ static PanelLockdown panel_lockdown = { 0, };
+
+
+@@ -63,9 +75,17 @@
+ panel_lockdown_invoke_closures (PanelLockdown *lockdown)
+ {
+ GSList *l;
++ GSList *copy = NULL;
+
+- for (l = lockdown->closures; l; l = l->next)
++ copy = g_slist_copy (lockdown->closures);
++ for (l = copy; l != NULL; l = l->next) {
++ if (g_slist_find (lockdown->closures, l->data)) {
++ g_closure_ref (l->data);
+ g_closure_invoke (l->data, NULL, 0, NULL, NULL);
++ g_closure_unref (l->data);
++ }
++ }
++ g_slist_free (copy);
+ }
+
+ static void
+@@ -166,6 +186,50 @@
+ panel_lockdown_invoke_closures (lockdown);
+ }
+
++static void
++restrict_application_launching_notify (GConfClient *client,
++ guint cnxn_id,
++ GConfEntry *entry,
++ PanelLockdown *lockdown)
++{
++ if (!entry->value || entry->value->type != GCONF_VALUE_BOOL)
++ return;
++
++ lockdown->restrict_application_launching =
++ gconf_value_get_bool (entry->value);
++
++ panel_lockdown_invoke_closures (lockdown);
++}
++
++
++static void
++allowed_applications_notify (GConfClient *client,
++ guint cnxn_id,
++ GConfEntry *entry,
++ PanelLockdown *lockdown)
++{
++ GSList *l;
++
++ if (!entry->value || entry->value->type != GCONF_VALUE_LIST ||
++ gconf_value_get_list_type (entry->value) != GCONF_VALUE_STRING)
++ return;
++
++ for (l = lockdown->allowed_applications; l; l = l->next)
++ g_free (l->data);
++ g_slist_free (lockdown->allowed_applications);
++ lockdown->allowed_applications = NULL;
++
++ for (l = gconf_value_get_list (entry->value); l; l = l->next) {
++ const char *iid = gconf_value_get_string (l->data);
++
++ lockdown->allowed_applications =
++ g_slist_prepend (lockdown->allowed_applications,
++ g_strdup (iid));
++ }
++
++ panel_lockdown_invoke_closures (lockdown);
++}
++
+ static gboolean
+ panel_lockdown_load_bool (PanelLockdown *lockdown,
+ GConfClient *client,
+@@ -215,6 +279,28 @@
+ return retval;
+ }
+
++static GSList *
++panel_lockdown_load_allowed_applications (PanelLockdown *lockdown,
++ GConfClient *client,
++ int listener)
++{
++ GSList *retval;
++
++ retval = gconf_client_get_list (client,
++ ALLOWED_APPLICATIONS_KEY,
++ GCONF_VALUE_STRING,
++ NULL);
++
++ lockdown->listeners [listener] =
++ gconf_client_notify_add (client,
++ ALLOWED_APPLICATIONS_KEY,
++ (GConfClientNotifyFunc) allowed_applications_notify,
++ lockdown,
++ NULL, NULL);
++
++ return retval;
++}
++
+ void
+ panel_lockdown_init (void)
+ {
+@@ -273,6 +359,18 @@
+ client,
+ i++);
+
++ panel_lockdown.restrict_application_launching =
++ panel_lockdown_load_bool (&panel_lockdown,
++ client,
++ RESTRICT_APPLICATION_LAUNCHING_KEY,
++ (GConfClientNotifyFunc) restrict_application_launching_notify,
++ i++);
++
++ panel_lockdown.allowed_applications =
++ panel_lockdown_load_allowed_applications (&panel_lockdown,
++ client,
++ i++);
++
+ g_assert (i == N_LISTENERS);
+
+ panel_lockdown.initialized = TRUE;
+@@ -294,6 +392,13 @@
+ g_slist_free (panel_lockdown.disabled_applets);
+ panel_lockdown.disabled_applets = NULL;
+
++ for (l = panel_lockdown.allowed_applications; l; l = l->next) {
++ g_free (l->data);
++ }
++
++ g_slist_free (panel_lockdown.allowed_applications);
++ panel_lockdown.allowed_applications = NULL;
++
+ for (i = 0; i < N_LISTENERS; i++) {
+ if (panel_lockdown.listeners [i])
+ gconf_client_notify_remove (client,
+@@ -371,6 +476,36 @@
+ return FALSE;
+ }
+
++gboolean
++panel_lockdown_get_restrict_application_launching (void)
++{
++ g_assert (panel_lockdown.initialized != FALSE);
++
++ return panel_lockdown.restrict_application_launching;
++}
++
++GSList *
++panel_lockdown_get_allowed_applications (void)
++{
++ g_assert (panel_lockdown.initialized == TRUE);
++
++ return panel_lockdown.allowed_applications;
++}
++
++gboolean
++panel_lockdown_is_allowed_application (const gchar *app)
++{
++ GSList *l;
++
++ g_assert (panel_lockdown.initialized != FALSE);
++
++ for (l = panel_lockdown.allowed_applications; l; l = l->next)
++ if (!strcmp (l->data, app))
++ return TRUE;
++
++ return FALSE;
++}
++
+ static GClosure *
+ panel_lockdown_notify_find (GSList *closures,
+ GCallback callback_func,
+@@ -440,3 +575,155 @@
+
+ g_closure_unref (closure);
+ }
++
++gchar *
++panel_lockdown_get_stripped_exec (const gchar *full_exec)
++{
++ gchar *str1, *str2, *retval, *p;
++
++ str1 = g_strdup (full_exec);
++ p = strtok (str1, " ");
++
++ if (p != NULL)
++ str2 = g_strdup (p);
++ else
++ str2 = g_strdup (full_exec);
++
++ g_free (str1);
++
++ if (g_path_is_absolute (str2))
++ retval = g_strdup (str2);
++ else
++ retval = g_strdup (g_find_program_in_path ((const gchar *)str2));
++ g_free (str2);
++
++ return retval;
++}
++
++gchar *
++panel_lockdown_get_exec_from_ditem (GnomeDesktopItem *ditem)
++{
++ const char *full_exec;
++ gchar *retval = NULL;
++
++ full_exec = gnome_desktop_item_get_string (ditem,
++ GNOME_DESKTOP_ITEM_EXEC);
++
++ if (full_exec != NULL)
++ retval = panel_lockdown_get_stripped_exec (full_exec);
++
++ return retval;
++}
++
++gboolean
++panel_lockdown_ditem_in_allowed_applications (GnomeDesktopItem *ditem)
++{
++ gboolean retval = FALSE;
++ gchar *stripped_exec;
++
++ stripped_exec = panel_lockdown_get_exec_from_ditem (ditem);
++
++ if (stripped_exec != NULL) {
++ retval = panel_lockdown_is_allowed_application (stripped_exec);
++ g_free (stripped_exec);
++ }
++
++ return retval;
++}
++
++gboolean
++panel_lockdown_is_disabled_command_line (const gchar *term_cmd)
++{
++ int i = 0;
++ gboolean retval = FALSE;
++
++ for (i=0; i<NUMBER_COMMAND_LINE_EXECS; i++) {
++ if (!strcmp (command_line_execs [i], term_cmd)) {
++ retval = TRUE;
++ break;
++ }
++ }
++
++ return retval;
++}
++
++gboolean
++panel_lockdown_is_forbidden_app(GnomeDesktopItem *ditem) {
++ g_return_val_if_fail (ditem != NULL, TRUE) ;
++ return panel_lockdown_get_restrict_application_launching () &&
++ !panel_lockdown_ditem_in_allowed_applications (ditem) ;
++}
++
++gboolean
++panel_lockdown_is_forbidden_ditem(GnomeDesktopItem *ditem)
++{
++ g_return_val_if_fail (ditem != NULL, TRUE) ;
++ if (panel_lockdown_is_forbidden_app (ditem)) { return TRUE ; }
++ if (panel_lockdown_get_disable_command_line ()) {
++ char *stripped = panel_lockdown_get_exec_from_ditem (ditem) ;
++
++ if (stripped != NULL) {
++ gboolean retCode =
++ panel_lockdown_is_disabled_command_line (stripped) ;
++
++ g_free (stripped) ;
++ return retCode ;
++ }
++ }
++ return FALSE ;
++}
++
++gboolean
++panel_lockdown_is_forbidden_command (const char *command)
++{
++ g_return_val_if_fail (command != NULL, TRUE) ;
++ return panel_lockdown_get_restrict_application_launching () &&
++ !panel_lockdown_is_allowed_application (command) ;
++}
++
++gboolean
++panel_lockdown_is_allowed_menu_entry (GMenuTreeEntry *entry)
++{
++ const char *path;
++ GnomeDesktopItem *item = NULL ;
++
++ if (!panel_lockdown_get_restrict_application_launching ())
++ return TRUE;
++
++ path = gmenu_tree_entry_get_desktop_file_path (entry) ;
++
++ if (path != NULL) {
++ item = gnome_desktop_item_new_from_file (path, 0, NULL) ;
++ if (item != NULL) {
++ gboolean retCode = !panel_lockdown_is_forbidden_ditem (item) ;
++
++ gnome_desktop_item_unref (item) ;
++ return retCode ;
++ }
++ }
++ return TRUE ;
++}
++
++gboolean
++panel_lockdown_is_forbidden_launcher (Launcher *launcher)
++{
++ return (panel_lockdown_is_forbidden_key_file(launcher->key_file));
++}
++
++gboolean
++panel_lockdown_is_forbidden_key_file (GKeyFile *key_file)
++{
++ gchar *full_exec; /* Executable including possible arguments */
++ gchar *stripped_exec; /* Executable with arguments stripped away */
++ gboolean retval = FALSE;
++
++ if (key_file != NULL)
++ {
++ full_exec = panel_util_key_file_get_string (key_file, "Exec");
++ if (full_exec != NULL) {
++ stripped_exec = panel_lockdown_get_stripped_exec (full_exec);
++ retval = panel_lockdown_is_forbidden_command (stripped_exec);
++ }
++ }
++ return retval;
++}
+--- gnome-panel-2.15.91.old/gnome-panel/panel-menu-items.c 2006-08-11 08:42:26.037425000 +0100
++++ gnome-panel-2.15.91/gnome-panel/panel-menu-items.c 2006-08-11 09:15:12.818522000 +0100
+@@ -1087,8 +1087,10 @@
+ tooltip = NULL;
+ }
+
+- item = panel_menu_items_create_action_item_full (PANEL_ACTION_LOGOUT,
+- label, tooltip);
++ if (!panel_lockdown_get_disable_log_out ()) {
++ item = panel_menu_items_create_action_item_full (PANEL_ACTION_LOGOUT,
++ label, tooltip);
++ }
+ g_free (label);
+ g_free (tooltip);
+
+@@ -1113,7 +1115,16 @@
+ const char *path)
+ {
+ GError *error;
++ GnomeDesktopItem *ditem;
+
++ if (g_path_is_absolute (path))
++ ditem = gnome_desktop_item_new_from_file (path, 0, NULL);
++ else
++ ditem = gnome_desktop_item_new_from_basename (path, 0, NULL);
++
++ if (ditem != NULL && panel_lockdown_is_forbidden_ditem (ditem))
++ return; /* Don't launch as it's a forbidden desktop file */
++
+ error = NULL;
+ panel_launch_desktop_file (path, NULL,
+ menuitem_to_screen (menuitem), &error);
+--- gnome-panel-2.15.91.old/gnome-panel/launcher.c 2006-08-11 14:19:58.478443000 +0100
++++ gnome-panel-2.15.91/gnome-panel/launcher.c 2006-08-11 14:19:37.592452000 +0100
+@@ -118,6 +118,10 @@
+ g_return_if_fail (launcher != NULL);
+ g_return_if_fail (launcher->key_file != NULL);
+
++/* LOCKDOWN FIXME - Need to ensure this is enough for launching a url */
++ if (!panel_lockdown_is_forbidden_launcher (launcher))
++ return;
++
+ /* FIXME panel_ditem_launch() should be enough for this! */
+ url = panel_util_key_file_get_string (launcher->key_file, "URL");
+
+@@ -166,6 +170,9 @@
+ g_return_if_fail (launcher != NULL);
+ g_return_if_fail (launcher->key_file != NULL);
+
++ if (panel_lockdown_is_forbidden_launcher (launcher))
++ return;
++
+ if (panel_global_config_get_enable_animations ())
+ xstuff_zoom_animate (widget, NULL);
+
+@@ -516,7 +523,12 @@
+ FALSE,
+ PANEL_ORIENTATION_TOP);
+
+- gtk_widget_show (launcher->button);
++ if (panel_lockdown_is_forbidden_launcher (launcher)) {
++ gtk_widget_hide (launcher->button);
++ }
++ else {
++ gtk_widget_show (launcher->button);
++ }
+
+ /*gtk_drag_dest_set (GTK_WIDGET (launcher->button),
+ GTK_DEST_DEFAULT_ALL,
+@@ -925,6 +937,10 @@
+ if (file != NULL)
+ panel_util_key_file_set_string (key_file, "Exec", file);
+ panel_util_key_file_set_string (key_file, "Type", "Application");
++
++ if (panel_lockdown_is_forbidden_key_file (key_file))
++ return; /* Application being dragged is forbidden so just return */
++
+ panel_ditem_editor_sync_display (PANEL_DITEM_EDITOR (dialog));
+
+ panel_ditem_register_save_uri_func (PANEL_DITEM_EDITOR (dialog),
+@@ -979,15 +995,18 @@
+ }
+
+ location = panel_make_unique_uri (NULL, ".desktop");
+- if (panel_util_key_file_to_file (key_file, location, &error)) {
+- panel_launcher_create (toplevel, position, location);
+- } else {
+- panel_error_dialog (NULL,
+- gtk_window_get_screen (GTK_WINDOW (toplevel)),
+- "cannot_save_launcher", TRUE,
+- _("Could not save launcher"),
+- error->message);
+- g_error_free (error);
++
++ if (!panel_lockdown_is_forbidden_key_file (key_file)) {
++ if (panel_util_key_file_to_file (key_file, location, &error)) {
++ panel_launcher_create (toplevel, position, location);
++ } else {
++ panel_error_dialog (NULL,
++ gtk_window_get_screen (GTK_WINDOW (toplevel)),
++ "cannot_save_launcher", TRUE,
++ _("Could not save launcher"),
++ error->message);
++ g_error_free (error);
++ }
+ }
+
+ g_key_file_free (key_file);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/gnome-panel-08-launch-menu.diff Fri Oct 20 15:31:04 2006 +0000
@@ -0,0 +1,357 @@
+diff -urN gnome-panel-2.14.1/gnome-panel/menu.c gnome-panel-2.14.1-hacked/gnome-panel/menu.c
+--- gnome-panel-2.14.1/gnome-panel/menu.c 2006-05-19 00:09:10.798983000 +1200
++++ gnome-panel-2.14.1-hacked/gnome-panel/menu.c 2006-05-19 00:11:22.657948000 +1200
+@@ -49,6 +49,8 @@
+ #include "panel-run-dialog.h"
+ #include "panel-lockdown.h"
+
++#define COMPUTER_NAME_KEY "/apps/nautilus/desktop/computer_icon_name"
++
+ typedef struct {
+ GtkWidget *pixmap;
+ const char *stock_id;
+@@ -1779,12 +1781,93 @@
+ }
+
+ static void
++run_applications (GtkWidget *widget, gpointer user_data)
++{
++ if (!panel_lockdown_get_restrict_application_launching() &&
++ !panel_lockdown_get_disable_command_line()) {
++ panel_run_dialog_present (gtk_widget_get_screen (widget),
++ gtk_get_current_event_time ());
++ }
++}
++
++static void
++applications_menu_append (GtkWidget *main_menu)
++{
++ GtkWidget *item;
++ GtkWidget *accel_label;
++ GtkWidget *image;
++
++ if (panel_lockdown_get_disable_command_line())
++ return;
++
++ if (!g_object_get_data (G_OBJECT (main_menu),
++ "panel-menu-needs-appending"))
++ return;
++
++ g_object_set_data (G_OBJECT (main_menu),
++ "panel-menu-needs-appending", NULL);
++
++ add_menu_separator (main_menu);
++
++ item = gtk_image_menu_item_new ();
++
++ accel_label = gtk_accel_label_new (_("Run Application..."));
++ gtk_misc_set_alignment (GTK_MISC (accel_label), 0.0, 0.5);
++
++ gtk_container_add (GTK_CONTAINER (item), accel_label);
++ gtk_accel_label_set_accel_widget (GTK_ACCEL_LABEL (accel_label),
++ GTK_WIDGET (item));
++ gtk_widget_show (accel_label);
++
++ image = gtk_image_new_from_icon_name (PANEL_RUN_ICON, panel_menu_icon_get_size ());
++ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
++
++ g_signal_connect (item, "activate",
++ G_CALLBACK (run_applications), NULL);
++ gtk_menu_shell_append (GTK_MENU_SHELL (main_menu), item);
++ gtk_widget_show (item);
++}
++
++GtkWidget *
++add_xdg_menu (const char *name, const char *path, const char *icon)
++{
++ GtkWidget *item;
++ GtkWidget *accel_label;
++ GtkWidget *image;
++ GtkWidget *menu;
++
++ item = gtk_image_menu_item_new ();
++
++ accel_label = gtk_accel_label_new (name);
++ gtk_misc_set_alignment (GTK_MISC (accel_label), 0.0, 0.5);
++
++ gtk_container_add (GTK_CONTAINER (item), accel_label);
++ gtk_accel_label_set_accel_widget (GTK_ACCEL_LABEL (accel_label),
++ GTK_WIDGET (item));
++ gtk_widget_show (accel_label);
++
++ image = gtk_image_new_from_icon_name (icon, panel_menu_icon_get_size ());
++
++ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
++ menu = create_applications_menu (path, NULL);
++
++ if (strcmp (path, "applications.menu") == 0) {
++ g_signal_connect (menu, "show",
++ G_CALLBACK (applications_menu_append), NULL);
++ }
++
++ gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), menu);
++
++ return item;
++}
++
++static void
+ main_menu_append (GtkWidget *main_menu,
+ PanelWidget *panel)
+ {
+ GtkWidget *item;
+- gboolean add_separator;
+- GList *children;
++ GtkRecentManager *recent_view;
++ char *gconf_name;
+
+ if (!g_object_get_data (G_OBJECT (main_menu),
+ "panel-menu-needs-appending"))
+@@ -1793,44 +1876,63 @@
+ g_object_set_data (G_OBJECT (main_menu),
+ "panel-menu-needs-appending", NULL);
+
+- children = gtk_container_get_children (GTK_CONTAINER (main_menu));
++ item = add_xdg_menu (_("All Applications"), "applications.menu", "gnome-applications");
++ gtk_menu_shell_append (GTK_MENU_SHELL (main_menu), item);
++ gtk_widget_show (item);
+
+- add_separator = FALSE;
+- if (children != NULL) {
+- while (children->next != NULL)
+- children = children->next;
+- add_separator = !GTK_IS_SEPARATOR (GTK_WIDGET (children->data));
+- }
++ add_menu_separator (main_menu);
+
+- if (add_separator)
+- add_menu_separator (main_menu);
++ gconf_name = gconf_client_get_string (panel_gconf_get_client (),
++ COMPUTER_NAME_KEY,
++ NULL);
++ panel_menu_items_append_from_desktop (main_menu,
++ "nautilus-computer.desktop",
++ gconf_name);
++ if (gconf_name)
++ g_free (gconf_name);
+
+ item = panel_place_menu_item_new (TRUE);
+ panel_place_menu_item_set_panel (item, panel);
+ gtk_menu_shell_append (GTK_MENU_SHELL (main_menu), item);
+ gtk_widget_show (item);
+
+- item = panel_desktop_menu_item_new (TRUE, FALSE);
+- panel_desktop_menu_item_set_panel (item, panel);
+- gtk_menu_shell_append (GTK_MENU_SHELL (main_menu), item);
++ recent_view = NULL;
++ panel_recent_append_documents_menu (main_menu, recent_view);
++ panel_menu_items_append_from_desktop (main_menu,
++ "gnome-search-tool.desktop",
++ NULL);
++
++ add_menu_separator (main_menu);
++
++ item = add_xdg_menu (_("Preferences"), "preferences.menu", "gnome-settings");
++ gtk_menu_shell_append (GTK_MENU_SHELL (main_menu), item);
++ gtk_widget_show (item);
++
++ item = add_xdg_menu (_("Administration"), "settings.menu", "gnome-system");
++ gtk_menu_shell_append (GTK_MENU_SHELL (main_menu), item);
+ gtk_widget_show (item);
+
++ panel_menu_items_append_from_desktop (main_menu,
++ "yelp.desktop",
++ NULL);
++
+ panel_menu_items_append_lock_logout (main_menu);
+ }
+
+ GtkWidget *
+ create_main_menu (PanelWidget *panel)
+ {
+- GtkWidget *main_menu;
++ GtkWidget *main_menu;
++
++ main_menu = create_applications_menu ("quickstart.menu", NULL);
+
+- main_menu = create_applications_menu ("applications.menu", NULL);
+- g_object_set_data (G_OBJECT (main_menu), "menu_panel", panel);
+- /* FIXME need to update the panel on parent_set */
++ g_object_set_data (G_OBJECT (main_menu), "menu_panel", panel);
++ /* FIXME need to update the panel on parent_set */
+
+- g_signal_connect (main_menu, "show",
+- G_CALLBACK (main_menu_append), panel);
++ g_signal_connect (main_menu, "show",
++ G_CALLBACK (main_menu_append), panel);
+
+- return main_menu;
++ return main_menu;
+ }
+
+ static GList *
+diff -urN gnome-panel-2.14.1/gnome-panel/panel-menu-button.c gnome-panel-2.14.1-hacked/gnome-panel/panel-menu-button.c
+--- gnome-panel-2.14.1/gnome-panel/panel-menu-button.c 2006-05-19 00:09:10.874287000 +1200
++++ gnome-panel-2.14.1-hacked/gnome-panel/panel-menu-button.c 2006-05-19 00:06:05.180856000 +1200
+@@ -38,6 +38,8 @@
+ #include "panel-lockdown.h"
+ #include "panel-a11y.h"
+
++#define COMPUTER_NAME_KEY "/apps/nautilus/desktop/computer_icon_name"
++
+ #define PANEL_MENU_BUTTON_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PANEL_TYPE_MENU_BUTTON, PanelMenuButtonPrivate))
+
+ enum {
+@@ -398,6 +400,18 @@
+ }
+
+ static void
++panel_menu_button_reload_menus (GConfClient *client,
++ guint cnxn_id,
++ GConfEntry *entry,
++ PanelMenuButton *button)
++{
++ if (button->priv->menu) {
++ gtk_widget_destroy (GTK_WIDGET (button->priv->menu));
++ panel_menu_button_create_menu (button);
++ }
++}
++
++static void
+ panel_menu_button_recreate_menu (PanelMenuButton *button)
+ {
+ if (button->priv->menu)
+@@ -694,6 +708,11 @@
+
+ panel_lockdown_notify_add (G_CALLBACK (panel_menu_button_recreate_menu),
+ button);
++
++ panel_gconf_notify_add_while_alive (COMPUTER_NAME_KEY,
++ (GConfClientNotifyFunc) panel_menu_button_reload_menus,
++ G_OBJECT (button));
++
+ }
+
+ static char *
+diff -urN gnome-panel-2.14.1/gnome-panel/panel-menu-items.h gnome-panel-2.14.1-hacked/gnome-panel/panel-menu-items.h
+--- gnome-panel-2.14.1/gnome-panel/panel-menu-items.h 2006-01-23 04:01:31.000000000 +1300
++++ gnome-panel-2.14.1-hacked/gnome-panel/panel-menu-items.h 2006-05-19 00:06:05.126410000 +1200
+@@ -90,6 +90,9 @@
+ void panel_menu_items_append_lock_logout (GtkWidget *menu);
+ void panel_menu_item_activate_desktop_file (GtkWidget *menuitem,
+ const char *path);
++void panel_menu_items_append_from_desktop (GtkWidget *menu,
++ char *path,
++ char *force_name);
+
+ G_END_DECLS
+
+--- gnome-panel-2.16.1.old/gnome-panel/panel-menu-items.c 2006-10-19 17:57:18.365107000 +0100
++++ gnome-panel-2.16.1/gnome-panel/panel-menu-items.c 2006-10-19 18:07:00.812807000 +0100
+@@ -54,8 +54,6 @@
+ #define DESKTOP_IS_HOME_DIR_DIR "/apps/nautilus/preferences"
+ #define DESKTOP_IS_HOME_DIR_KEY "/apps/nautilus/preferences/desktop_is_home_dir"
+ #define NAMES_DIR "/apps/nautilus/desktop"
+-#define HOME_NAME_KEY "/apps/nautilus/desktop/home_icon_name"
+-#define COMPUTER_NAME_KEY "/apps/nautilus/desktop/computer_icon_name"
+ #define MAX_ITEMS_OR_SUBMENU 5
+
+ #define PANEL_PLACE_MENU_ITEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PANEL_TYPE_PLACE_MENU_ITEM, PanelPlaceMenuItemPrivate))
+@@ -120,7 +118,7 @@
+ g_free (url);
+ }
+
+-static void
++void
+ panel_menu_items_append_from_desktop (GtkWidget *menu,
+ char *path,
+ char *force_name)
+@@ -559,18 +557,10 @@
+ GtkWidget *places_menu;
+ GtkWidget *item;
+ char *gconf_name;
++ char *documents_link;
+
+ places_menu = panel_create_menu ();
+
+- gconf_name = gconf_client_get_string (panel_gconf_get_client (),
+- HOME_NAME_KEY,
+- NULL);
+- panel_menu_items_append_from_desktop (places_menu,
+- "nautilus-home.desktop",
+- gconf_name);
+- if (gconf_name)
+- g_free (gconf_name);
+-
+ if (!gconf_client_get_bool (panel_gconf_get_client (),
+ DESKTOP_IS_HOME_DIR_KEY,
+ NULL)) {
+@@ -594,18 +584,19 @@
+ g_free (uri);
+ }
+
++ documents_link = g_build_filename (g_get_home_dir (), "Documents", NULL);
++
++ panel_menu_items_append_place_item ("gnome-fs-directory",
++ _("Documents"),
++ _("Open your Documents folder"),
++ places_menu,
++ G_CALLBACK (activate_uri),
++ documents_link);
++ g_free (documents_link);
++
+ panel_place_menu_item_append_gtk_bookmarks (places_menu);
+ add_menu_separator (places_menu);
+
+- gconf_name = gconf_client_get_string (panel_gconf_get_client (),
+- COMPUTER_NAME_KEY,
+- NULL);
+- panel_menu_items_append_from_desktop (places_menu,
+- "nautilus-computer.desktop",
+- gconf_name);
+- if (gconf_name)
+- g_free (gconf_name);
+-
+ panel_menu_items_append_from_desktop (places_menu,
+ "nautilus-cd-burner.desktop",
+ NULL);
+@@ -625,15 +616,6 @@
+ item);
+ }
+
+- add_menu_separator (places_menu);
+-
+- panel_menu_items_append_from_desktop (places_menu,
+- "gnome-search-tool.desktop",
+- NULL);
+-
+- panel_recent_append_documents_menu (places_menu,
+- place_item->priv->recent_manager);
+-
+ return places_menu;
+ }
+
+@@ -805,15 +787,9 @@
+ GCONF_CLIENT_PRELOAD_NONE,
+ NULL);
+
+- panel_gconf_notify_add_while_alive (HOME_NAME_KEY,
+- (GConfClientNotifyFunc) panel_place_menu_item_key_changed,
+- G_OBJECT (menuitem));
+ panel_gconf_notify_add_while_alive (DESKTOP_IS_HOME_DIR_KEY,
+ (GConfClientNotifyFunc) panel_place_menu_item_key_changed,
+ G_OBJECT (menuitem));
+- panel_gconf_notify_add_while_alive (COMPUTER_NAME_KEY,
+- (GConfClientNotifyFunc) panel_place_menu_item_key_changed,
+- G_OBJECT (menuitem));
+
+ menuitem->priv->recent_manager = gtk_recent_manager_get_default ();
+
+@@ -948,7 +924,7 @@
+
+ menuitem = g_object_new (PANEL_TYPE_PLACE_MENU_ITEM, NULL);
+
+- accel_label = gtk_accel_label_new (_("Places"));
++ accel_label = gtk_accel_label_new (g_get_user_name ());
+ gtk_misc_set_alignment (GTK_MISC (accel_label), 0.0, 0.5);
+
+ gtk_container_add (GTK_CONTAINER (menuitem), accel_label);
--- a/patches/gnome-panel-08-restrict-app-launching.diff Fri Oct 20 15:24:25 2006 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,998 +0,0 @@
---- gnome-panel-2.15.91.old/gnome-panel/Makefile.am 2006-08-09 15:43:31.107934000 +0100
-+++ gnome-panel-2.15.91/gnome-panel/Makefile.am 2006-08-09 15:58:00.483203000 +0100
-@@ -167,6 +167,8 @@
- panel-ditem-editor.c \
- panel-marshal.c \
- panel-util.c \
-+ panel-lockdown.c \
-+ panel-gconf.c \
- xstuff.c
-
- gnome_desktop_item_edit_LDFLAGS = -export-dynamic
---- gnome-panel-2.15.91.old/gnome-panel/panel-util.c 2006-08-09 15:43:31.117319000 +0100
-+++ gnome-panel-2.15.91/gnome-panel/panel-util.c 2006-08-09 16:00:29.664793000 +0100
-@@ -34,6 +34,7 @@
- #include "xstuff.h"
- #include "panel-globals.h"
- #include "launcher.h"
-+#include "panel-lockdown.h"
-
- static int
- panel_ditem_launch (GnomeDesktopItem *item,
-@@ -705,6 +706,9 @@
- char *command = NULL;
- gboolean use_gscreensaver = FALSE;
-
-+ if (panel_lockdown_get_disable_lock_screen () )
-+ return NULL;
-+
- if (panel_is_program_in_path ("gnome-screensaver-command")
- && panel_is_program_in_path ("gnome-screensaver-preferences"))
- use_gscreensaver = TRUE;
---- gnome-panel-2.15.91.old/gnome-panel/menu.c 2006-08-09 15:43:31.124010000 +0100
-+++ gnome-panel-2.15.91/gnome-panel/menu.c 2006-08-09 17:39:54.146347000 +0100
-@@ -72,7 +72,8 @@
- static GSList *image_menu_items = NULL;
-
- static GtkWidget *populate_menu_from_directory (GtkWidget *menu,
-- GMenuTreeDirectory *directory);
-+ GMenuTreeDirectory *directory,
-+ gboolean *is_hidden);
-
- static void panel_load_menu_image_deferred (GtkWidget *image_menu_item,
- GtkIconSize icon_size,
-@@ -1308,7 +1309,8 @@
- }
-
- static void
--submenu_to_display (GtkWidget *menu)
-+submenu_to_display (GtkWidget *menu,
-+ gboolean *is_hidden)
- {
- GMenuTree *tree;
- GMenuTreeDirectory *directory;
-@@ -1340,18 +1342,27 @@
- (GDestroyNotify) gmenu_tree_item_unref);
- }
-
-- if (directory)
-- populate_menu_from_directory (menu, directory);
-+ if (directory) {
-+ /* It's possible that is_hidden is NULL if we end up here from the show
-+ signal, which could only happen for the top level menu. */
-+ gboolean local_is_hidden = FALSE;
-+
-+ populate_menu_from_directory (menu, directory, &local_is_hidden);
-+ if (is_hidden != NULL) {
-+ *is_hidden = local_is_hidden;
-+ }
-+ }
- }
-
- static gboolean
- submenu_to_display_in_idle (gpointer data)
- {
- GtkWidget *menu = GTK_WIDGET (data);
-+ gboolean is_hidden = FALSE;
-
- g_object_set_data (G_OBJECT (menu), "panel-menu-idle-id", NULL);
-
-- submenu_to_display (menu);
-+ submenu_to_display (menu, &is_hidden);
-
- return FALSE;
- }
-@@ -1437,28 +1448,41 @@
- static void
- create_submenu (GtkWidget *menu,
- GMenuTreeDirectory *directory,
-- GMenuTreeDirectory *alias_directory)
-+ GMenuTreeDirectory *alias_directory,
-+ gboolean *is_hidden)
- {
- GtkWidget *menuitem;
- GtkWidget *submenu;
-
-+ submenu = create_fake_menu (directory);
-+ if (panel_lockdown_get_restrict_application_launching ()) {
-+ submenu_to_display (submenu, is_hidden);
-+ }
-+ else {
-+ *is_hidden = FALSE;
-+ }
-+
- if (alias_directory)
- menuitem = create_submenu_entry (menu, alias_directory);
- else
- menuitem = create_submenu_entry (menu, directory);
-
-- submenu = create_fake_menu (directory);
--
- gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
-+
-+ if (*is_hidden) {
-+ gtk_widget_hide (menuitem);
-+ }
- }
-
- static void
- create_header (GtkWidget *menu,
-- GMenuTreeHeader *header)
-+ GMenuTreeHeader *header,
-+ gboolean *is_hidden)
- {
- GMenuTreeDirectory *directory;
- GtkWidget *menuitem;
-
-+ *is_hidden = FALSE;
- directory = gmenu_tree_header_get_directory (header);
- menuitem = create_submenu_entry (menu, directory);
- gmenu_tree_item_unref (directory);
-@@ -1475,10 +1499,12 @@
- static void
- create_menuitem (GtkWidget *menu,
- GMenuTreeEntry *entry,
-- GMenuTreeDirectory *alias_directory)
-+ GMenuTreeDirectory *alias_directory,
-+ gboolean *is_hidden)
- {
- GtkWidget *menuitem;
-
-+ *is_hidden = FALSE;
- menuitem = gtk_image_menu_item_new ();
-
- g_object_set_data_full (G_OBJECT (menuitem),
-@@ -1508,6 +1534,11 @@
- gmenu_tree_entry_get_name (entry),
- TRUE);
-
-+ if (entry != NULL && !panel_lockdown_is_allowed_menu_entry (entry)) {
-+ gtk_widget_hide (menuitem);
-+ *is_hidden = TRUE;
-+ }
-+
- if ((alias_directory &&
- gmenu_tree_directory_get_comment (alias_directory)) ||
- (!alias_directory &&
-@@ -1551,7 +1582,8 @@
-
- static void
- create_menuitem_from_alias (GtkWidget *menu,
-- GMenuTreeAlias *alias)
-+ GMenuTreeAlias *alias,
-+ gboolean *is_hidden)
- {
- GMenuTreeItem *aliased_item;
-
-@@ -1561,13 +1593,15 @@
- case GMENU_TREE_ITEM_DIRECTORY:
- create_submenu (menu,
- GMENU_TREE_DIRECTORY (aliased_item),
-- gmenu_tree_alias_get_directory (alias));
-+ gmenu_tree_alias_get_directory (alias),
-+ is_hidden);
- break;
-
- case GMENU_TREE_ITEM_ENTRY:
- create_menuitem (menu,
- GMENU_TREE_ENTRY (aliased_item),
-- gmenu_tree_alias_get_directory (alias));
-+ gmenu_tree_alias_get_directory (alias),
-+ is_hidden);
- break;
-
- default:
-@@ -1675,18 +1709,21 @@
-
- static GtkWidget *
- populate_menu_from_directory (GtkWidget *menu,
-- GMenuTreeDirectory *directory)
-+ GMenuTreeDirectory *directory,
-+ gboolean *is_hidden)
- {
- GSList *l;
- GSList *items;
- gboolean add_separator;
-
-+ *is_hidden = TRUE;
- add_separator = (GTK_MENU_SHELL (menu)->children != NULL);
-
- items = gmenu_tree_directory_get_contents (directory);
-
- for (l = items; l; l = l->next) {
- GMenuTreeItem *item = l->data;
-+ gboolean is_item_hidden = TRUE;
-
- if (add_separator ||
- gmenu_tree_item_get_type (item) == GMENU_TREE_ITEM_SEPARATOR) {
-@@ -1696,11 +1733,13 @@
-
- switch (gmenu_tree_item_get_type (item)) {
- case GMENU_TREE_ITEM_DIRECTORY:
-- create_submenu (menu, GMENU_TREE_DIRECTORY (item), NULL);
-+ create_submenu (menu, GMENU_TREE_DIRECTORY (item), NULL,
-+ &is_item_hidden);
- break;
-
- case GMENU_TREE_ITEM_ENTRY:
-- create_menuitem (menu, GMENU_TREE_ENTRY (item), NULL);
-+ create_menuitem (menu, GMENU_TREE_ENTRY (item), NULL,
-+ &is_item_hidden);
- break;
-
- case GMENU_TREE_ITEM_SEPARATOR :
-@@ -1708,11 +1747,13 @@
- break;
-
- case GMENU_TREE_ITEM_ALIAS:
-- create_menuitem_from_alias (menu, GMENU_TREE_ALIAS (item));
-+ create_menuitem_from_alias (menu, GMENU_TREE_ALIAS (item),
-+ &is_item_hidden);
- break;
-
- case GMENU_TREE_ITEM_HEADER:
-- create_header (menu, GMENU_TREE_HEADER (item));
-+ create_header (menu, GMENU_TREE_HEADER (item),
-+ &is_item_hidden);
- break;
-
- default:
-@@ -1720,6 +1761,9 @@
- }
-
- gmenu_tree_item_unref (item);
-+ if (!is_item_hidden) {
-+ *is_hidden = FALSE;
-+ }
- }
-
- g_slist_free (items);
---- gnome-panel-2.15.91.old/gnome-panel/panel-menu-bar.c 2006-08-09 15:43:31.127630000 +0100
-+++ gnome-panel-2.15.91/gnome-panel/panel-menu-bar.c 2006-08-09 18:01:50.710691000 +0100
-@@ -168,6 +168,17 @@
- "", NULL);
- }
-
-+static void
-+panel_menubar_recreate_menus (PanelMenuBar *menubar)
-+{
-+ if (menubar->priv->applications_menu != NULL) {
-+ while (GTK_MENU_SHELL (menubar->priv->applications_menu)->children) {
-+ gtk_widget_destroy (GTK_MENU_SHELL (menubar->priv->applications_menu)->children->data) ;
-+ }
-+ menubar->priv->applications_menu = create_applications_menu ("applications.menu", NULL) ;
-+ }
-+}
-+
- static void
- panel_menu_bar_instance_init (PanelMenuBar *menubar,
- PanelMenuBarClass *klass)
-@@ -200,6 +211,7 @@
- menubar->priv->desktop_item);
-
- panel_menu_bar_setup_tooltip (menubar);
-+ panel_lockdown_notify_add (G_CALLBACK (panel_menubar_recreate_menus), menubar);
- }
-
- static void
---- gnome-panel-2.15.91.old/gnome-panel/panel-addto.c 2006-08-09 15:43:31.406993000 +0100
-+++ gnome-panel-2.15.91/gnome-panel/panel-addto.c 2006-08-09 18:11:14.990889000 +0100
-@@ -558,9 +558,10 @@
- dialog, NULL);
- }
-
--static void panel_addto_make_application_list (GSList **parent_list,
-+static gint panel_addto_make_application_list (GSList **parent_list,
- GMenuTreeDirectory *directory,
- const char *filename);
-+static void panel_addto_dialog_free_item_info (PanelAddtoItemInfo *item_info);
-
- static void
- panel_addto_prepend_directory (GSList **parent_list,
-@@ -568,6 +569,7 @@
- const char *filename)
- {
- PanelAddtoAppList *data;
-+ gint entries_added = 0;
-
- data = g_new0 (PanelAddtoAppList, 1);
-
-@@ -587,9 +589,16 @@
- * So the iid is built when we select the row.
- */
-
-- *parent_list = g_slist_prepend (*parent_list, data);
--
-- panel_addto_make_application_list (&data->children, directory, filename);
-+ entries_added = panel_addto_make_application_list (&data->children, directory, filename);
-+ if (entries_added > 0) {
-+ /*Only prepend if there are entries */
-+ *parent_list = g_slist_prepend (*parent_list, data);
-+ }
-+ else {
-+ /* Free data as not being appended */
-+ panel_addto_dialog_free_item_info (&data->item_info);
-+ g_free (data);
-+ }
- }
-
- static void
-@@ -611,12 +620,13 @@
- *parent_list = g_slist_prepend (*parent_list, data);
- }
-
--static void
-+static gint
- panel_addto_prepend_alias (GSList **parent_list,
- GMenuTreeAlias *alias,
- const char *filename)
- {
- GMenuTreeItem *aliased_item;
-+ gint entry = 0;
-
- aliased_item = gmenu_tree_alias_get_item (alias);
-
-@@ -628,9 +638,12 @@
- break;
-
- case GMENU_TREE_ITEM_ENTRY:
-- panel_addto_prepend_entry (parent_list,
-- GMENU_TREE_ENTRY (aliased_item),
-- filename);
-+ if (panel_lockdown_is_allowed_menu_entry (GMENU_TREE_ENTRY (aliased_item))) {
-+ panel_addto_prepend_entry (parent_list,
-+ GMENU_TREE_ENTRY (aliased_item),
-+ filename);
-+ entry = 1;
-+ }
- break;
-
- default:
-@@ -638,15 +651,17 @@
- }
-
- gmenu_tree_item_unref (aliased_item);
-+ return entry;
- }
-
--static void
-+static gint
- panel_addto_make_application_list (GSList **parent_list,
- GMenuTreeDirectory *directory,
- const char *filename)
- {
- GSList *items;
- GSList *l;
-+ gint number_entries = 0;
-
- items = gmenu_tree_directory_get_contents (directory);
-
-@@ -657,11 +672,15 @@
- break;
-
- case GMENU_TREE_ITEM_ENTRY:
-- panel_addto_prepend_entry (parent_list, l->data, filename);
-+ if (panel_lockdown_is_allowed_menu_entry (l->data)) {
-+ panel_addto_prepend_entry (parent_list, l->data, filename);
-+ number_entries = number_entries + 1;
-+ }
- break;
-
- case GMENU_TREE_ITEM_ALIAS:
-- panel_addto_prepend_alias (parent_list, l->data, filename);
-+ number_entries = number_entries +
-+ panel_addto_prepend_alias (parent_list, l->data, filename);
- break;
-
- default:
-@@ -674,6 +693,8 @@
- g_slist_free (items);
-
- *parent_list = g_slist_reverse (*parent_list);
-+
-+ return number_entries;
- }
-
- static void
---- gnome-panel-2.15.91.old/gnome-panel/panel-action-button.c 2006-08-09 15:43:31.127312000 +0100
-+++ gnome-panel-2.15.91/gnome-panel/panel-action-button.c 2006-08-10 11:28:35.882566000 +0100
-@@ -178,8 +178,11 @@
- static void
- panel_action_run_program (GtkWidget *widget)
- {
-- panel_run_dialog_present (gtk_widget_get_screen (widget),
-- gtk_get_current_event_time ());
-+ if (!panel_lockdown_get_restrict_application_launching () &&
-+ !panel_lockdown_get_disable_command_line ()) {
-+ panel_run_dialog_present (gtk_widget_get_screen (widget),
-+ gtk_get_current_event_time ());
-+ }
- }
-
- /* Search For Files
-@@ -190,6 +193,11 @@
- GdkScreen *screen;
- GError *error = NULL;
-
-+ /* LOCKDOWN FIXME ---- FIX PATH --- */
-+ if (panel_lockdown_is_forbidden_command ("/usr/bin/gnome-search-tool")) {
-+ return;
-+ }
-+
- screen = gtk_widget_get_screen (widget);
- panel_launch_desktop_file ("gnome-search-tool.desktop",
- "gnome-search-tool",
---- gnome-panel-2.15.91.old/gnome-panel/gnome-desktop-item-edit.c 2006-08-10 14:12:18.746542000 +0100
-+++ gnome-panel-2.15.91/gnome-panel/gnome-desktop-item-edit.c 2006-08-10 14:12:12.298142000 +0100
-@@ -9,6 +9,7 @@
-
- #include "panel-ditem-editor.h"
- #include "panel-util.h"
-+#include "panel-lockdown.h"
-
- #include "nothing.cP"
-
-@@ -176,6 +177,8 @@
- bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
- textdomain (GETTEXT_PACKAGE);
-
-+ panel_lockdown_init ();
-+
- context = g_option_context_new (_("- Edit .desktop files"));
-
- g_option_context_add_main_entries (context, options, GETTEXT_PACKAGE);
-@@ -301,5 +304,7 @@
-
- g_object_unref (program);
-
-+ panel_lockdown_finalize ();
-+
- return 0;
- }
---- gnome-panel-2.15.91.old/gnome-panel/panel-lockdown.h 2006-08-10 17:07:04.897831000 +0100
-+++ gnome-panel-2.15.91/gnome-panel/panel-lockdown.h 2006-08-10 17:05:45.569877000 +0100
-@@ -25,8 +25,11 @@
- #ifndef __PANEL_LOCKDOWN_H__
- #define __PANEL_LOCKDOWN_H__
-
-+#include <libgnome/gnome-desktop-item.h>
- #include <glib.h>
- #include <glib-object.h>
-+#include <gmenu-tree.h>
-+#include "launcher.h"
-
- G_BEGIN_DECLS
-
-@@ -38,14 +41,56 @@
- gboolean panel_lockdown_get_disable_lock_screen (void);
- gboolean panel_lockdown_get_disable_log_out (void);
- gboolean panel_lockdown_get_disable_force_quit (void);
-+gboolean panel_lockdown_get_restrict_application_launching (void);
-+GSList *panel_lockdown_get_allowed_applications (void);
-
- gboolean panel_lockdown_is_applet_disabled (const char *iid);
-+gboolean panel_lockdown_is_allowed_application (const gchar *app);
-
- void panel_lockdown_notify_add (GCallback callback_func,
- gpointer user_data);
- void panel_lockdown_notify_remove (GCallback callback_func,
- gpointer user_data);
-
-+gchar *panel_lockdown_get_stripped_exec (const gchar *full_exec);
-+gchar *panel_lockdown_get_exec_from_ditem (GnomeDesktopItem *ditem);
-+gboolean panel_lockdown_ditem_in_allowed_applications (GnomeDesktopItem *ditem);
-+gboolean panel_lockdown_is_disabled_command_line (const gchar *term_cmd);
-+
-+/**
-+ * Returns true if the ditem corresponds to an application whose use has been
-+ * disallowed by the administrator (tests whether restrictions are in place
-+ * and if the ditem matches the allowed applications list).
-+ */
-+gboolean panel_lockdown_is_forbidden_app (GnomeDesktopItem *ditem);
-+/**
-+ * Returns true if the ditem corresponds to either an application whose use
-+ * has been disallowed by the administrator (same as previous function) or
-+ * a shell when command line use has been restricted.
-+ */
-+gboolean panel_lockdown_is_forbidden_ditem (GnomeDesktopItem *ditem);
-+/**
-+ * Returns true if the command line corresponds to an application whose use
-+ * has been disallowed by the administrator.
-+ */
-+gboolean panel_lockdown_is_forbidden_command (const gchar *command);
-+
-+/**
-+ * Returns true if the menu entry corresponds to an application whose use
-+ * has been allowed by the administrator.
-+ */
-+gboolean panel_lockdown_is_allowed_menu_entry (GMenuTreeEntry *entry);
-+
-+/**
-+ * Returns true if the launcher application has been disallowed by the administrator.
-+ */
-+gboolean panel_lockdown_is_forbidden_launcher (Launcher *launcher);
-+
-+/**
-+ * Returns true if the key_file application has been disallowed by the administrator.
-+ */
-+gboolean panel_lockdown_is_forbidden_key_file (GKeyFile *key_file);
-+
- G_END_DECLS
-
- #endif /* __PANEL_LOCKDOWN_H__ */
---- gnome-panel-2.15.91.old/gnome-panel/panel-lockdown.c 2006-08-10 17:28:30.033061000 +0100
-+++ gnome-panel-2.15.91/gnome-panel/panel-lockdown.c 2006-08-10 17:27:59.592217000 +0100
-@@ -28,13 +28,16 @@
-
- #include <string.h>
- #include "panel-gconf.h"
-+#include "panel-util.h"
-
--#define N_LISTENERS 6
-+#define N_LISTENERS 8
-
- #define PANEL_GLOBAL_LOCKDOWN_DIR "/apps/panel/global"
- #define DESKTOP_GNOME_LOCKDOWN_DIR "/desktop/gnome/lockdown"
- #define PANEL_GLOBAL_LOCKED_DOWN_KEY PANEL_GLOBAL_LOCKDOWN_DIR "/locked_down"
- #define DISABLE_COMMAND_LINE_KEY DESKTOP_GNOME_LOCKDOWN_DIR "/disable_command_line"
-+#define RESTRICT_APPLICATION_LAUNCHING_KEY DESKTOP_GNOME_LOCKDOWN_DIR "/restrict_application_launching"
-+#define ALLOWED_APPLICATIONS_KEY DESKTOP_GNOME_LOCKDOWN_DIR "/allowed_applications"
- #define DISABLE_LOCK_SCREEN_KEY PANEL_GLOBAL_LOCKDOWN_DIR "/disable_lock_screen"
- #define DISABLE_LOG_OUT_KEY PANEL_GLOBAL_LOCKDOWN_DIR "/disable_log_out"
- #define DISABLE_FORCE_QUIT_KEY PANEL_GLOBAL_LOCKDOWN_DIR "/disable_force_quit"
-@@ -48,6 +51,9 @@
- guint disable_lock_screen : 1;
- guint disable_log_out : 1;
- guint disable_force_quit : 1;
-+ guint restrict_application_launching : 1;
-+
-+ GSList *allowed_applications;
-
- GSList *disabled_applets;
-
-@@ -56,6 +62,12 @@
- GSList *closures;
- } PanelLockdown;
-
-+static const gchar *command_line_execs[] = {
-+ "/usr/bin/gnome-terminal",
-+ "/usr/bin/xterm"
-+};
-+#define NUMBER_COMMAND_LINE_EXECS 2
-+
- static PanelLockdown panel_lockdown = { 0, };
-
-
-@@ -63,9 +75,17 @@
- panel_lockdown_invoke_closures (PanelLockdown *lockdown)
- {
- GSList *l;
-+ GSList *copy = NULL;
-
-- for (l = lockdown->closures; l; l = l->next)
-+ copy = g_slist_copy (lockdown->closures);
-+ for (l = copy; l != NULL; l = l->next) {
-+ if (g_slist_find (lockdown->closures, l->data)) {
-+ g_closure_ref (l->data);
- g_closure_invoke (l->data, NULL, 0, NULL, NULL);
-+ g_closure_unref (l->data);
-+ }
-+ }
-+ g_slist_free (copy);
- }
-
- static void
-@@ -166,6 +186,50 @@
- panel_lockdown_invoke_closures (lockdown);
- }
-
-+static void
-+restrict_application_launching_notify (GConfClient *client,
-+ guint cnxn_id,
-+ GConfEntry *entry,
-+ PanelLockdown *lockdown)
-+{
-+ if (!entry->value || entry->value->type != GCONF_VALUE_BOOL)
-+ return;
-+
-+ lockdown->restrict_application_launching =
-+ gconf_value_get_bool (entry->value);
-+
-+ panel_lockdown_invoke_closures (lockdown);
-+}
-+
-+
-+static void
-+allowed_applications_notify (GConfClient *client,
-+ guint cnxn_id,
-+ GConfEntry *entry,
-+ PanelLockdown *lockdown)
-+{
-+ GSList *l;
-+
-+ if (!entry->value || entry->value->type != GCONF_VALUE_LIST ||
-+ gconf_value_get_list_type (entry->value) != GCONF_VALUE_STRING)
-+ return;
-+
-+ for (l = lockdown->allowed_applications; l; l = l->next)
-+ g_free (l->data);
-+ g_slist_free (lockdown->allowed_applications);
-+ lockdown->allowed_applications = NULL;
-+
-+ for (l = gconf_value_get_list (entry->value); l; l = l->next) {
-+ const char *iid = gconf_value_get_string (l->data);
-+
-+ lockdown->allowed_applications =
-+ g_slist_prepend (lockdown->allowed_applications,
-+ g_strdup (iid));
-+ }
-+
-+ panel_lockdown_invoke_closures (lockdown);
-+}
-+
- static gboolean
- panel_lockdown_load_bool (PanelLockdown *lockdown,
- GConfClient *client,
-@@ -215,6 +279,28 @@
- return retval;
- }
-
-+static GSList *
-+panel_lockdown_load_allowed_applications (PanelLockdown *lockdown,
-+ GConfClient *client,
-+ int listener)
-+{
-+ GSList *retval;
-+
-+ retval = gconf_client_get_list (client,
-+ ALLOWED_APPLICATIONS_KEY,
-+ GCONF_VALUE_STRING,
-+ NULL);
-+
-+ lockdown->listeners [listener] =
-+ gconf_client_notify_add (client,
-+ ALLOWED_APPLICATIONS_KEY,
-+ (GConfClientNotifyFunc) allowed_applications_notify,
-+ lockdown,
-+ NULL, NULL);
-+
-+ return retval;
-+}
-+
- void
- panel_lockdown_init (void)
- {
-@@ -273,6 +359,18 @@
- client,
- i++);
-
-+ panel_lockdown.restrict_application_launching =
-+ panel_lockdown_load_bool (&panel_lockdown,
-+ client,
-+ RESTRICT_APPLICATION_LAUNCHING_KEY,
-+ (GConfClientNotifyFunc) restrict_application_launching_notify,
-+ i++);
-+
-+ panel_lockdown.allowed_applications =
-+ panel_lockdown_load_allowed_applications (&panel_lockdown,
-+ client,
-+ i++);
-+
- g_assert (i == N_LISTENERS);
-
- panel_lockdown.initialized = TRUE;
-@@ -294,6 +392,13 @@
- g_slist_free (panel_lockdown.disabled_applets);
- panel_lockdown.disabled_applets = NULL;
-
-+ for (l = panel_lockdown.allowed_applications; l; l = l->next) {
-+ g_free (l->data);
-+ }
-+
-+ g_slist_free (panel_lockdown.allowed_applications);
-+ panel_lockdown.allowed_applications = NULL;
-+
- for (i = 0; i < N_LISTENERS; i++) {
- if (panel_lockdown.listeners [i])
- gconf_client_notify_remove (client,
-@@ -371,6 +476,36 @@
- return FALSE;
- }
-
-+gboolean
-+panel_lockdown_get_restrict_application_launching (void)
-+{
-+ g_assert (panel_lockdown.initialized != FALSE);
-+
-+ return panel_lockdown.restrict_application_launching;
-+}
-+
-+GSList *
-+panel_lockdown_get_allowed_applications (void)
-+{
-+ g_assert (panel_lockdown.initialized == TRUE);
-+
-+ return panel_lockdown.allowed_applications;
-+}
-+
-+gboolean
-+panel_lockdown_is_allowed_application (const gchar *app)
-+{
-+ GSList *l;
-+
-+ g_assert (panel_lockdown.initialized != FALSE);
-+
-+ for (l = panel_lockdown.allowed_applications; l; l = l->next)
-+ if (!strcmp (l->data, app))
-+ return TRUE;
-+
-+ return FALSE;
-+}
-+
- static GClosure *
- panel_lockdown_notify_find (GSList *closures,
- GCallback callback_func,
-@@ -440,3 +575,155 @@
-
- g_closure_unref (closure);
- }
-+
-+gchar *
-+panel_lockdown_get_stripped_exec (const gchar *full_exec)
-+{
-+ gchar *str1, *str2, *retval, *p;
-+
-+ str1 = g_strdup (full_exec);
-+ p = strtok (str1, " ");
-+
-+ if (p != NULL)
-+ str2 = g_strdup (p);
-+ else
-+ str2 = g_strdup (full_exec);
-+
-+ g_free (str1);
-+
-+ if (g_path_is_absolute (str2))
-+ retval = g_strdup (str2);
-+ else
-+ retval = g_strdup (g_find_program_in_path ((const gchar *)str2));
-+ g_free (str2);
-+
-+ return retval;
-+}
-+
-+gchar *
-+panel_lockdown_get_exec_from_ditem (GnomeDesktopItem *ditem)
-+{
-+ const char *full_exec;
-+ gchar *retval = NULL;
-+
-+ full_exec = gnome_desktop_item_get_string (ditem,
-+ GNOME_DESKTOP_ITEM_EXEC);
-+
-+ if (full_exec != NULL)
-+ retval = panel_lockdown_get_stripped_exec (full_exec);
-+
-+ return retval;
-+}
-+
-+gboolean
-+panel_lockdown_ditem_in_allowed_applications (GnomeDesktopItem *ditem)
-+{
-+ gboolean retval = FALSE;
-+ gchar *stripped_exec;
-+
-+ stripped_exec = panel_lockdown_get_exec_from_ditem (ditem);
-+
-+ if (stripped_exec != NULL) {
-+ retval = panel_lockdown_is_allowed_application (stripped_exec);
-+ g_free (stripped_exec);
-+ }
-+
-+ return retval;
-+}
-+
-+gboolean
-+panel_lockdown_is_disabled_command_line (const gchar *term_cmd)
-+{
-+ int i = 0;
-+ gboolean retval = FALSE;
-+
-+ for (i=0; i<NUMBER_COMMAND_LINE_EXECS; i++) {
-+ if (!strcmp (command_line_execs [i], term_cmd)) {
-+ retval = TRUE;
-+ break;
-+ }
-+ }
-+
-+ return retval;
-+}
-+
-+gboolean
-+panel_lockdown_is_forbidden_app(GnomeDesktopItem *ditem) {
-+ g_return_val_if_fail (ditem != NULL, TRUE) ;
-+ return panel_lockdown_get_restrict_application_launching () &&
-+ !panel_lockdown_ditem_in_allowed_applications (ditem) ;
-+}
-+
-+gboolean
-+panel_lockdown_is_forbidden_ditem(GnomeDesktopItem *ditem)
-+{
-+ g_return_val_if_fail (ditem != NULL, TRUE) ;
-+ if (panel_lockdown_is_forbidden_app (ditem)) { return TRUE ; }
-+ if (panel_lockdown_get_disable_command_line ()) {
-+ char *stripped = panel_lockdown_get_exec_from_ditem (ditem) ;
-+
-+ if (stripped != NULL) {
-+ gboolean retCode =
-+ panel_lockdown_is_disabled_command_line (stripped) ;
-+
-+ g_free (stripped) ;
-+ return retCode ;
-+ }
-+ }
-+ return FALSE ;
-+}
-+
-+gboolean
-+panel_lockdown_is_forbidden_command (const char *command)
-+{
-+ g_return_val_if_fail (command != NULL, TRUE) ;
-+ return panel_lockdown_get_restrict_application_launching () &&
-+ !panel_lockdown_is_allowed_application (command) ;
-+}
-+
-+gboolean
-+panel_lockdown_is_allowed_menu_entry (GMenuTreeEntry *entry)
-+{
-+ const char *path;
-+ GnomeDesktopItem *item = NULL ;
-+
-+ if (!panel_lockdown_get_restrict_application_launching ())
-+ return TRUE;
-+
-+ path = gmenu_tree_entry_get_desktop_file_path (entry) ;
-+
-+ if (path != NULL) {
-+ item = gnome_desktop_item_new_from_file (path, 0, NULL) ;
-+ if (item != NULL) {
-+ gboolean retCode = !panel_lockdown_is_forbidden_ditem (item) ;
-+
-+ gnome_desktop_item_unref (item) ;
-+ return retCode ;
-+ }
-+ }
-+ return TRUE ;
-+}
-+
-+gboolean
-+panel_lockdown_is_forbidden_launcher (Launcher *launcher)
-+{
-+ return (panel_lockdown_is_forbidden_key_file(launcher->key_file));
-+}
-+
-+gboolean
-+panel_lockdown_is_forbidden_key_file (GKeyFile *key_file)
-+{
-+ gchar *full_exec; /* Executable including possible arguments */
-+ gchar *stripped_exec; /* Executable with arguments stripped away */
-+ gboolean retval = FALSE;
-+
-+ if (key_file != NULL)
-+ {
-+ full_exec = panel_util_key_file_get_string (key_file, "Exec");
-+ if (full_exec != NULL) {
-+ stripped_exec = panel_lockdown_get_stripped_exec (full_exec);
-+ retval = panel_lockdown_is_forbidden_command (stripped_exec);
-+ }
-+ }
-+ return retval;
-+}
---- gnome-panel-2.15.91.old/gnome-panel/panel-menu-items.c 2006-08-11 08:42:26.037425000 +0100
-+++ gnome-panel-2.15.91/gnome-panel/panel-menu-items.c 2006-08-11 09:15:12.818522000 +0100
-@@ -1087,8 +1087,10 @@
- tooltip = NULL;
- }
-
-- item = panel_menu_items_create_action_item_full (PANEL_ACTION_LOGOUT,
-- label, tooltip);
-+ if (!panel_lockdown_get_disable_log_out ()) {
-+ item = panel_menu_items_create_action_item_full (PANEL_ACTION_LOGOUT,
-+ label, tooltip);
-+ }
- g_free (label);
- g_free (tooltip);
-
-@@ -1113,7 +1115,16 @@
- const char *path)
- {
- GError *error;
-+ GnomeDesktopItem *ditem;
-
-+ if (g_path_is_absolute (path))
-+ ditem = gnome_desktop_item_new_from_file (path, 0, NULL);
-+ else
-+ ditem = gnome_desktop_item_new_from_basename (path, 0, NULL);
-+
-+ if (ditem != NULL && panel_lockdown_is_forbidden_ditem (ditem))
-+ return; /* Don't launch as it's a forbidden desktop file */
-+
- error = NULL;
- panel_launch_desktop_file (path, NULL,
- menuitem_to_screen (menuitem), &error);
---- gnome-panel-2.15.91.old/gnome-panel/launcher.c 2006-08-11 14:19:58.478443000 +0100
-+++ gnome-panel-2.15.91/gnome-panel/launcher.c 2006-08-11 14:19:37.592452000 +0100
-@@ -118,6 +118,10 @@
- g_return_if_fail (launcher != NULL);
- g_return_if_fail (launcher->key_file != NULL);
-
-+/* LOCKDOWN FIXME - Need to ensure this is enough for launching a url */
-+ if (!panel_lockdown_is_forbidden_launcher (launcher))
-+ return;
-+
- /* FIXME panel_ditem_launch() should be enough for this! */
- url = panel_util_key_file_get_string (launcher->key_file, "URL");
-
-@@ -166,6 +170,9 @@
- g_return_if_fail (launcher != NULL);
- g_return_if_fail (launcher->key_file != NULL);
-
-+ if (panel_lockdown_is_forbidden_launcher (launcher))
-+ return;
-+
- if (panel_global_config_get_enable_animations ())
- xstuff_zoom_animate (widget, NULL);
-
-@@ -516,7 +523,12 @@
- FALSE,
- PANEL_ORIENTATION_TOP);
-
-- gtk_widget_show (launcher->button);
-+ if (panel_lockdown_is_forbidden_launcher (launcher)) {
-+ gtk_widget_hide (launcher->button);
-+ }
-+ else {
-+ gtk_widget_show (launcher->button);
-+ }
-
- /*gtk_drag_dest_set (GTK_WIDGET (launcher->button),
- GTK_DEST_DEFAULT_ALL,
-@@ -925,6 +937,10 @@
- if (file != NULL)
- panel_util_key_file_set_string (key_file, "Exec", file);
- panel_util_key_file_set_string (key_file, "Type", "Application");
-+
-+ if (panel_lockdown_is_forbidden_key_file (key_file))
-+ return; /* Application being dragged is forbidden so just return */
-+
- panel_ditem_editor_sync_display (PANEL_DITEM_EDITOR (dialog));
-
- panel_ditem_register_save_uri_func (PANEL_DITEM_EDITOR (dialog),
-@@ -979,15 +995,18 @@
- }
-
- location = panel_make_unique_uri (NULL, ".desktop");
-- if (panel_util_key_file_to_file (key_file, location, &error)) {
-- panel_launcher_create (toplevel, position, location);
-- } else {
-- panel_error_dialog (NULL,
-- gtk_window_get_screen (GTK_WINDOW (toplevel)),
-- "cannot_save_launcher", TRUE,
-- _("Could not save launcher"),
-- error->message);
-- g_error_free (error);
-+
-+ if (!panel_lockdown_is_forbidden_key_file (key_file)) {
-+ if (panel_util_key_file_to_file (key_file, location, &error)) {
-+ panel_launcher_create (toplevel, position, location);
-+ } else {
-+ panel_error_dialog (NULL,
-+ gtk_window_get_screen (GTK_WINDOW (toplevel)),
-+ "cannot_save_launcher", TRUE,
-+ _("Could not save launcher"),
-+ error->message);
-+ g_error_free (error);
-+ }
- }
-
- g_key_file_free (key_file);
--- a/patches/gnome-panel-09-launch-menu.diff Fri Oct 20 15:24:25 2006 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,357 +0,0 @@
-diff -urN gnome-panel-2.14.1/gnome-panel/menu.c gnome-panel-2.14.1-hacked/gnome-panel/menu.c
---- gnome-panel-2.14.1/gnome-panel/menu.c 2006-05-19 00:09:10.798983000 +1200
-+++ gnome-panel-2.14.1-hacked/gnome-panel/menu.c 2006-05-19 00:11:22.657948000 +1200
-@@ -49,6 +49,8 @@
- #include "panel-run-dialog.h"
- #include "panel-lockdown.h"
-
-+#define COMPUTER_NAME_KEY "/apps/nautilus/desktop/computer_icon_name"
-+
- typedef struct {
- GtkWidget *pixmap;
- const char *stock_id;
-@@ -1779,12 +1781,93 @@
- }
-
- static void
-+run_applications (GtkWidget *widget, gpointer user_data)
-+{
-+ if (!panel_lockdown_get_restrict_application_launching() &&
-+ !panel_lockdown_get_disable_command_line()) {
-+ panel_run_dialog_present (gtk_widget_get_screen (widget),
-+ gtk_get_current_event_time ());
-+ }
-+}
-+
-+static void
-+applications_menu_append (GtkWidget *main_menu)
-+{
-+ GtkWidget *item;
-+ GtkWidget *accel_label;
-+ GtkWidget *image;
-+
-+ if (panel_lockdown_get_disable_command_line())
-+ return;
-+
-+ if (!g_object_get_data (G_OBJECT (main_menu),
-+ "panel-menu-needs-appending"))
-+ return;
-+
-+ g_object_set_data (G_OBJECT (main_menu),
-+ "panel-menu-needs-appending", NULL);
-+
-+ add_menu_separator (main_menu);
-+
-+ item = gtk_image_menu_item_new ();
-+
-+ accel_label = gtk_accel_label_new (_("Run Application..."));
-+ gtk_misc_set_alignment (GTK_MISC (accel_label), 0.0, 0.5);
-+
-+ gtk_container_add (GTK_CONTAINER (item), accel_label);
-+ gtk_accel_label_set_accel_widget (GTK_ACCEL_LABEL (accel_label),
-+ GTK_WIDGET (item));
-+ gtk_widget_show (accel_label);
-+
-+ image = gtk_image_new_from_icon_name (PANEL_RUN_ICON, panel_menu_icon_get_size ());
-+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
-+
-+ g_signal_connect (item, "activate",
-+ G_CALLBACK (run_applications), NULL);
-+ gtk_menu_shell_append (GTK_MENU_SHELL (main_menu), item);
-+ gtk_widget_show (item);
-+}
-+
-+GtkWidget *
-+add_xdg_menu (const char *name, const char *path, const char *icon)
-+{
-+ GtkWidget *item;
-+ GtkWidget *accel_label;
-+ GtkWidget *image;
-+ GtkWidget *menu;
-+
-+ item = gtk_image_menu_item_new ();
-+
-+ accel_label = gtk_accel_label_new (name);
-+ gtk_misc_set_alignment (GTK_MISC (accel_label), 0.0, 0.5);
-+
-+ gtk_container_add (GTK_CONTAINER (item), accel_label);
-+ gtk_accel_label_set_accel_widget (GTK_ACCEL_LABEL (accel_label),
-+ GTK_WIDGET (item));
-+ gtk_widget_show (accel_label);
-+
-+ image = gtk_image_new_from_icon_name (icon, panel_menu_icon_get_size ());
-+
-+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
-+ menu = create_applications_menu (path, NULL);
-+
-+ if (strcmp (path, "applications.menu") == 0) {
-+ g_signal_connect (menu, "show",
-+ G_CALLBACK (applications_menu_append), NULL);
-+ }
-+
-+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), menu);
-+
-+ return item;
-+}
-+
-+static void
- main_menu_append (GtkWidget *main_menu,
- PanelWidget *panel)
- {
- GtkWidget *item;
-- gboolean add_separator;
-- GList *children;
-+ GtkRecentManager *recent_view;
-+ char *gconf_name;
-
- if (!g_object_get_data (G_OBJECT (main_menu),
- "panel-menu-needs-appending"))
-@@ -1793,44 +1876,63 @@
- g_object_set_data (G_OBJECT (main_menu),
- "panel-menu-needs-appending", NULL);
-
-- children = gtk_container_get_children (GTK_CONTAINER (main_menu));
-+ item = add_xdg_menu (_("All Applications"), "applications.menu", "gnome-applications");
-+ gtk_menu_shell_append (GTK_MENU_SHELL (main_menu), item);
-+ gtk_widget_show (item);
-
-- add_separator = FALSE;
-- if (children != NULL) {
-- while (children->next != NULL)
-- children = children->next;
-- add_separator = !GTK_IS_SEPARATOR (GTK_WIDGET (children->data));
-- }
-+ add_menu_separator (main_menu);
-
-- if (add_separator)
-- add_menu_separator (main_menu);
-+ gconf_name = gconf_client_get_string (panel_gconf_get_client (),
-+ COMPUTER_NAME_KEY,
-+ NULL);
-+ panel_menu_items_append_from_desktop (main_menu,
-+ "nautilus-computer.desktop",
-+ gconf_name);
-+ if (gconf_name)
-+ g_free (gconf_name);
-
- item = panel_place_menu_item_new (TRUE);
- panel_place_menu_item_set_panel (item, panel);
- gtk_menu_shell_append (GTK_MENU_SHELL (main_menu), item);
- gtk_widget_show (item);
-
-- item = panel_desktop_menu_item_new (TRUE, FALSE);
-- panel_desktop_menu_item_set_panel (item, panel);
-- gtk_menu_shell_append (GTK_MENU_SHELL (main_menu), item);
-+ recent_view = NULL;
-+ panel_recent_append_documents_menu (main_menu, recent_view);
-+ panel_menu_items_append_from_desktop (main_menu,
-+ "gnome-search-tool.desktop",
-+ NULL);
-+
-+ add_menu_separator (main_menu);
-+
-+ item = add_xdg_menu (_("Preferences"), "preferences.menu", "gnome-settings");
-+ gtk_menu_shell_append (GTK_MENU_SHELL (main_menu), item);
-+ gtk_widget_show (item);
-+
-+ item = add_xdg_menu (_("Administration"), "settings.menu", "gnome-system");
-+ gtk_menu_shell_append (GTK_MENU_SHELL (main_menu), item);
- gtk_widget_show (item);
-
-+ panel_menu_items_append_from_desktop (main_menu,
-+ "yelp.desktop",
-+ NULL);
-+
- panel_menu_items_append_lock_logout (main_menu);
- }
-
- GtkWidget *
- create_main_menu (PanelWidget *panel)
- {
-- GtkWidget *main_menu;
-+ GtkWidget *main_menu;
-+
-+ main_menu = create_applications_menu ("quickstart.menu", NULL);
-
-- main_menu = create_applications_menu ("applications.menu", NULL);
-- g_object_set_data (G_OBJECT (main_menu), "menu_panel", panel);
-- /* FIXME need to update the panel on parent_set */
-+ g_object_set_data (G_OBJECT (main_menu), "menu_panel", panel);
-+ /* FIXME need to update the panel on parent_set */
-
-- g_signal_connect (main_menu, "show",
-- G_CALLBACK (main_menu_append), panel);
-+ g_signal_connect (main_menu, "show",
-+ G_CALLBACK (main_menu_append), panel);
-
-- return main_menu;
-+ return main_menu;
- }
-
- static GList *
-diff -urN gnome-panel-2.14.1/gnome-panel/panel-menu-button.c gnome-panel-2.14.1-hacked/gnome-panel/panel-menu-button.c
---- gnome-panel-2.14.1/gnome-panel/panel-menu-button.c 2006-05-19 00:09:10.874287000 +1200
-+++ gnome-panel-2.14.1-hacked/gnome-panel/panel-menu-button.c 2006-05-19 00:06:05.180856000 +1200
-@@ -38,6 +38,8 @@
- #include "panel-lockdown.h"
- #include "panel-a11y.h"
-
-+#define COMPUTER_NAME_KEY "/apps/nautilus/desktop/computer_icon_name"
-+
- #define PANEL_MENU_BUTTON_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PANEL_TYPE_MENU_BUTTON, PanelMenuButtonPrivate))
-
- enum {
-@@ -398,6 +400,18 @@
- }
-
- static void
-+panel_menu_button_reload_menus (GConfClient *client,
-+ guint cnxn_id,
-+ GConfEntry *entry,
-+ PanelMenuButton *button)
-+{
-+ if (button->priv->menu) {
-+ gtk_widget_destroy (GTK_WIDGET (button->priv->menu));
-+ panel_menu_button_create_menu (button);
-+ }
-+}
-+
-+static void
- panel_menu_button_recreate_menu (PanelMenuButton *button)
- {
- if (button->priv->menu)
-@@ -694,6 +708,11 @@
-
- panel_lockdown_notify_add (G_CALLBACK (panel_menu_button_recreate_menu),
- button);
-+
-+ panel_gconf_notify_add_while_alive (COMPUTER_NAME_KEY,
-+ (GConfClientNotifyFunc) panel_menu_button_reload_menus,
-+ G_OBJECT (button));
-+
- }
-
- static char *
-diff -urN gnome-panel-2.14.1/gnome-panel/panel-menu-items.h gnome-panel-2.14.1-hacked/gnome-panel/panel-menu-items.h
---- gnome-panel-2.14.1/gnome-panel/panel-menu-items.h 2006-01-23 04:01:31.000000000 +1300
-+++ gnome-panel-2.14.1-hacked/gnome-panel/panel-menu-items.h 2006-05-19 00:06:05.126410000 +1200
-@@ -90,6 +90,9 @@
- void panel_menu_items_append_lock_logout (GtkWidget *menu);
- void panel_menu_item_activate_desktop_file (GtkWidget *menuitem,
- const char *path);
-+void panel_menu_items_append_from_desktop (GtkWidget *menu,
-+ char *path,
-+ char *force_name);
-
- G_END_DECLS
-
---- gnome-panel-2.16.1.old/gnome-panel/panel-menu-items.c 2006-10-19 17:57:18.365107000 +0100
-+++ gnome-panel-2.16.1/gnome-panel/panel-menu-items.c 2006-10-19 18:07:00.812807000 +0100
-@@ -54,8 +54,6 @@
- #define DESKTOP_IS_HOME_DIR_DIR "/apps/nautilus/preferences"
- #define DESKTOP_IS_HOME_DIR_KEY "/apps/nautilus/preferences/desktop_is_home_dir"
- #define NAMES_DIR "/apps/nautilus/desktop"
--#define HOME_NAME_KEY "/apps/nautilus/desktop/home_icon_name"
--#define COMPUTER_NAME_KEY "/apps/nautilus/desktop/computer_icon_name"
- #define MAX_ITEMS_OR_SUBMENU 5
-
- #define PANEL_PLACE_MENU_ITEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PANEL_TYPE_PLACE_MENU_ITEM, PanelPlaceMenuItemPrivate))
-@@ -120,7 +118,7 @@
- g_free (url);
- }
-
--static void
-+void
- panel_menu_items_append_from_desktop (GtkWidget *menu,
- char *path,
- char *force_name)
-@@ -559,18 +557,10 @@
- GtkWidget *places_menu;
- GtkWidget *item;
- char *gconf_name;
-+ char *documents_link;
-
- places_menu = panel_create_menu ();
-
-- gconf_name = gconf_client_get_string (panel_gconf_get_client (),
-- HOME_NAME_KEY,
-- NULL);
-- panel_menu_items_append_from_desktop (places_menu,
-- "nautilus-home.desktop",
-- gconf_name);
-- if (gconf_name)
-- g_free (gconf_name);
--
- if (!gconf_client_get_bool (panel_gconf_get_client (),
- DESKTOP_IS_HOME_DIR_KEY,
- NULL)) {
-@@ -594,18 +584,19 @@
- g_free (uri);
- }
-
-+ documents_link = g_build_filename (g_get_home_dir (), "Documents", NULL);
-+
-+ panel_menu_items_append_place_item ("gnome-fs-directory",
-+ _("Documents"),
-+ _("Open your Documents folder"),
-+ places_menu,
-+ G_CALLBACK (activate_uri),
-+ documents_link);
-+ g_free (documents_link);
-+
- panel_place_menu_item_append_gtk_bookmarks (places_menu);
- add_menu_separator (places_menu);
-
-- gconf_name = gconf_client_get_string (panel_gconf_get_client (),
-- COMPUTER_NAME_KEY,
-- NULL);
-- panel_menu_items_append_from_desktop (places_menu,
-- "nautilus-computer.desktop",
-- gconf_name);
-- if (gconf_name)
-- g_free (gconf_name);
--
- panel_menu_items_append_from_desktop (places_menu,
- "nautilus-cd-burner.desktop",
- NULL);
-@@ -625,15 +616,6 @@
- item);
- }
-
-- add_menu_separator (places_menu);
--
-- panel_menu_items_append_from_desktop (places_menu,
-- "gnome-search-tool.desktop",
-- NULL);
--
-- panel_recent_append_documents_menu (places_menu,
-- place_item->priv->recent_manager);
--
- return places_menu;
- }
-
-@@ -805,15 +787,9 @@
- GCONF_CLIENT_PRELOAD_NONE,
- NULL);
-
-- panel_gconf_notify_add_while_alive (HOME_NAME_KEY,
-- (GConfClientNotifyFunc) panel_place_menu_item_key_changed,
-- G_OBJECT (menuitem));
- panel_gconf_notify_add_while_alive (DESKTOP_IS_HOME_DIR_KEY,
- (GConfClientNotifyFunc) panel_place_menu_item_key_changed,
- G_OBJECT (menuitem));
-- panel_gconf_notify_add_while_alive (COMPUTER_NAME_KEY,
-- (GConfClientNotifyFunc) panel_place_menu_item_key_changed,
-- G_OBJECT (menuitem));
-
- menuitem->priv->recent_manager = gtk_recent_manager_get_default ();
-
-@@ -948,7 +924,7 @@
-
- menuitem = g_object_new (PANEL_TYPE_PLACE_MENU_ITEM, NULL);
-
-- accel_label = gtk_accel_label_new (_("Places"));
-+ accel_label = gtk_accel_label_new (g_get_user_name ());
- gtk_misc_set_alignment (GTK_MISC (accel_label), 0.0, 0.5);
-
- gtk_container_add (GTK_CONTAINER (menuitem), accel_label);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/gnome-panel-09-solaris-branding.diff Fri Oct 20 15:31:04 2006 +0000
@@ -0,0 +1,36 @@
+--- gnome-panel-2.16.0/gnome-panel/panel-menu-button.c 2006-09-21 16:21:12.547123000 +0200
++++ ../gnome-panel-2.16.0/gnome-panel/panel-menu-button.c 2006-09-21 16:15:16.549802000 +0200
+@@ -692,7 +692,7 @@
+ "tooltip", tooltip,
+ "use-menu-path", use_menu_path,
+ "use-custom-icon", use_custom_icon,
+- "has-arrow", TRUE,
++ "has-arrow", FALSE,
+ NULL);
+
+ info = panel_applet_register (GTK_WIDGET (button), NULL, NULL,
+@@ -772,7 +772,23 @@
+ }
+
+ if (!retval)
+- retval = g_strdup (PANEL_MAIN_MENU_ICON);
++ {
++ static gboolean inited = FALSE;
++ static gboolean has_sun_branding = FALSE;
++
++ if (!inited)
++ {
++ GtkIconTheme *theme = gtk_icon_theme_get_default ();
++ if (gtk_icon_theme_has_icon (theme, "sun-start-here"))
++ has_sun_branding = TRUE;
++ inited = TRUE;
++ }
++
++ if (has_sun_branding)
++ retval = g_strdup ("sun-start-here");
++ else
++ retval = g_strdup (PANEL_MAIN_MENU_ICON);
++ }
+
+ return retval;
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/gnome-panel-10-clock-timezone.diff Fri Oct 20 15:31:04 2006 +0000
@@ -0,0 +1,5191 @@
+diff -Nrup gnome-panel-2.14.1/applets/clock/clock.h ../gnome-panel-2.14.1/applets/clock/clock.h
+--- gnome-panel-2.14.1/applets/clock/clock.h 1970-01-01 01:00:00.000000000 +0100
++++ ../gnome-panel-2.14.1/applets/clock/clock.h 2006-06-12 16:18:42.518645000 +0200
+@@ -0,0 +1,176 @@
++#ifndef __CLOCK_H__
++#define __CLOCK_H__
++
++#include <stdio.h>
++#include <sys/stat.h>
++#include <unistd.h>
++#include <dirent.h>
++#include <string.h>
++#include <time.h>
++#include <langinfo.h>
++
++#include <panel-applet.h>
++#include <panel-applet-gconf.h>
++
++#include <gtk/gtk.h>
++#include <gdk/gdkkeysyms.h>
++#include <libbonobo.h>
++#include <gconf/gconf-client.h>
++#include <libgnomeui/gnome-help.h>
++#include <libgnome/gnome-init.h>
++#include <libgnomeui/gnome-url.h>
++
++#include <glade/glade.h>
++
++#ifdef HAVE_LIBECAL
++#include "calendar-client.h"
++#endif
++#include "tz.h"
++#include "e-map/e-map.h"
++
++#define INTERNETSECOND (864)
++#define INTERNETBEAT (86400)
++
++#define N_GCONF_PREFS 8
++
++#define NEVER_SENSITIVE "never_sensitive"
++
++typedef struct _ClockData ClockData;
++typedef struct _TimezoneSelectionDialog TimezoneSelectionDialog;
++typedef struct _TipZone TipZone;
++
++typedef enum {
++ CLOCK_FORMAT_INVALID = 0,
++ CLOCK_FORMAT_12,
++ CLOCK_FORMAT_24,
++ CLOCK_FORMAT_UNIX,
++ CLOCK_FORMAT_INTERNET,
++ CLOCK_FORMAT_CUSTOM
++} ClockFormat;
++
++struct _ClockData {
++ /* widgets */
++ GtkWidget *applet;
++ GtkWidget *clockw;
++ GtkWidget *toggle;
++ GtkWidget *props;
++ GtkWidget *about;
++ GtkWidget *calendar_popup;
++ GtkWidget *calendar;
++ GtkWidget *timezone_dialog;
++ GtkWidget *multizone_popup;
++
++
++ GtkWidget *hbox;
++
++ GtkWidget *multizone_toggle;
++ GtkWidget *multizone_image;
++ GdkPixbuf *image;
++
++#ifdef HAVE_LIBECAL
++ GtkWidget *task_list;
++ GtkWidget *appointment_list;
++
++ GtkListStore *appointments_model;
++ GtkListStore *tasks_model;
++ GtkTreeModelFilter *tasks_filter;
++
++ CalendarClient *client;
++#endif /* HAVE_LIBECAL */
++
++ /* preferences */
++ ClockFormat format;
++ char *custom_format;
++ gboolean showseconds;
++ gboolean showdate;
++ gboolean gmt_time;
++ gboolean showweek;
++ gboolean show_multiple_timezones;
++
++ char *config_tool;
++
++ /* runtime data */
++ time_t current_time;
++ char *timeformat;
++ guint timeout;
++ PanelAppletOrient orient;
++ int size;
++ int save_allocation_h;
++ int save_allocation_w;
++
++ TimezoneSelectionDialog *tsd;
++ GSList *tip_list;
++ TzDB *tzdb;
++
++ int fixed_width;
++ int fixed_height;
++
++ GtkWidget *showseconds_check;
++ GtkWidget *showdate_check;
++ GtkWidget *gmt_time_check;
++ GtkWidget *custom_hbox;
++ GtkWidget *custom_label;
++ GtkWidget *custom_entry;
++ GtkWidget *showzones_check;
++ gboolean custom_format_shown;
++
++ gboolean can_handle_format_12;
++
++ guint listeners [N_GCONF_PREFS];
++};
++
++void
++clock_set_tooltip (GtkWidget *applet,
++ GtkWidget *widget,
++ const char *tip);
++
++
++#define TZ_MAP_POINT_NORMAL_RGBA 0xc070a0ff
++#define TZ_MAP_POINT_HOVER_RGBA 0xffff60ff
++#define TZ_MAP_POINT_SELECTED_1_RGBA 0xff60e0ff
++#define TZ_MAP_POINT_SELECTED_2_RGBA 0x000000ff
++
++
++struct _TimezoneSelectionDialog
++{
++ GtkWidget *dialog;
++ GladeXML *xml;
++
++ EMapPoint *point_selected;
++ EMapPoint *point_hover;
++ EMap *map;
++ glong correction;
++ char *zone;
++
++ guint timeout;
++
++ /* multi timezone part */
++ GtkWidget *tips_tree;
++ GtkTreeStore *model;
++
++ ClockData *cd;
++};
++
++void
++display_timezone_selection_dialog (BonoboUIComponent *uic,
++ ClockData *cd,
++ const gchar *verbname);
++
++/* multi-timezone part */
++
++
++struct _TipZone {
++ char *zone;
++ char *nick;
++ GtkWidget *time_label;
++ GtkWidget *nick_label;
++};
++
++GtkWidget * create_multi_timezones_popup (ClockData *cd,
++ GdkScreen *screen);
++void create_multizone_table (TimezoneSelectionDialog *tsd);
++void timzone_dialog_set_zones_only (TimezoneSelectionDialog *tsd);
++void timzone_dialog_set_main_zone_only (TimezoneSelectionDialog *tsd);
++gboolean multizone_is_zone_in_tip_list (ClockData *cd, char *zone);
++#endif /* __CLOCK_H__ */
++
+diff -Nrup gnome-panel-2.14.1/applets/clock/clock.schemas.in ../gnome-panel-2.14.1/applets/clock/clock.schemas.in
+--- gnome-panel-2.14.1/applets/clock/clock.schemas.in 2006-06-12 16:19:24.709455000 +0200
++++ ../gnome-panel-2.14.1/applets/clock/clock.schemas.in 2006-06-12 16:18:42.506318000 +0200
+@@ -174,6 +174,18 @@
+ </locale>
+ </schema>
+
++ <schema>
++ <key>/schemas/apps/clock_applet/prefs/show_zones</key>
++ <owner>clock-applet</owner>
++ <type>bool</type>
++ <default>false</default>
++ <locale name="C">
++ <short>Show the timezone button</short>
++ <long>If true, display the timezone button in the clock, in addition to time.</long>
++ </locale>
++ </schema>
++
++
+ </schemalist>
+
+ </gconfschemafile>
+diff -Nrup gnome-panel-2.14.1/applets/clock/e-map/Makefile.am ../gnome-panel-2.14.1/applets/clock/e-map/Makefile.am
+--- gnome-panel-2.14.1/applets/clock/e-map/Makefile.am 1970-01-01 01:00:00.000000000 +0100
++++ ../gnome-panel-2.14.1/applets/clock/e-map/Makefile.am 2006-06-12 16:18:42.525973000 +0200
+@@ -0,0 +1,32 @@
++INCLUDES = \
++ -DPACKAGE_DATA_DIR=\""$(datadir)/gnome/panel/pixmaps"\" \
++ -DPACKAGE_LOCALE_DIR=\""$(prefix)/$(DATADIRNAME)/locale"\" \
++ $(WARN_CFLAGS) \
++ $(FISH_CFLAGS)
++
++EXTRA_DIST= e-map-marshal.list
++
++e-map-marshal.h: e-map-marshal.list
++ ( @GLIB_GENMARSHAL@ e-map-marshal.list --header > e-map-marshal.tmp \
++ && mv e-map-marshal.tmp e-map-marshal.h ) \
++ || ( rm -f e-map-marshal.tmp && exit 1 )
++
++e-map-marshal.c: e-map-marshal.h
++ ( @GLIB_GENMARSHAL@ e-map-marshal.list --body > e-map-marshal.tmp \
++ && mv e-map-marshal.tmp e-map-marshal.c ) \
++ || ( rm -f e-map-marshal.tmp && exit 1 )
++
++$(e_map_la_OBJECTS): e-map-marshal.h
++
++noinst_LIBRARIES = libemap.a
++
++libemap_a_CFLAGS = \
++ $(GNOME_CFLAGS) \
++ $(GDK_PIXBUF_CFLAGS)
++
++BUILT_SOURCES= e-map-marshal.c e-map-marshal.h
++
++libemap_a_SOURCES = \
++ e-map.c e-map.h \
++ e-map-marshal.c e-map-marshal.h
++
+diff -Nrup gnome-panel-2.14.1/applets/clock/e-map/e-map-marshal.c ../gnome-panel-2.14.1/applets/clock/e-map/e-map-marshal.c
+--- gnome-panel-2.14.1/applets/clock/e-map/e-map-marshal.c 1970-01-01 01:00:00.000000000 +0100
++++ ../gnome-panel-2.14.1/applets/clock/e-map/e-map-marshal.c 2006-06-12 16:18:42.714593000 +0200
+@@ -0,0 +1,86 @@
++
++#include <glib-object.h>
++
++
++#ifdef G_ENABLE_DEBUG
++#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v)
++#define g_marshal_value_peek_char(v) g_value_get_char (v)
++#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v)
++#define g_marshal_value_peek_int(v) g_value_get_int (v)
++#define g_marshal_value_peek_uint(v) g_value_get_uint (v)
++#define g_marshal_value_peek_long(v) g_value_get_long (v)
++#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v)
++#define g_marshal_value_peek_int64(v) g_value_get_int64 (v)
++#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v)
++#define g_marshal_value_peek_enum(v) g_value_get_enum (v)
++#define g_marshal_value_peek_flags(v) g_value_get_flags (v)
++#define g_marshal_value_peek_float(v) g_value_get_float (v)
++#define g_marshal_value_peek_double(v) g_value_get_double (v)
++#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v)
++#define g_marshal_value_peek_param(v) g_value_get_param (v)
++#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v)
++#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v)
++#define g_marshal_value_peek_object(v) g_value_get_object (v)
++#else /* !G_ENABLE_DEBUG */
++/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API.
++ * Do not access GValues directly in your code. Instead, use the
++ * g_value_get_*() functions
++ */
++#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int
++#define g_marshal_value_peek_char(v) (v)->data[0].v_int
++#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint
++#define g_marshal_value_peek_int(v) (v)->data[0].v_int
++#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint
++#define g_marshal_value_peek_long(v) (v)->data[0].v_long
++#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong
++#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64
++#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64
++#define g_marshal_value_peek_enum(v) (v)->data[0].v_long
++#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong
++#define g_marshal_value_peek_float(v) (v)->data[0].v_float
++#define g_marshal_value_peek_double(v) (v)->data[0].v_double
++#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer
++#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer
++#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer
++#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer
++#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer
++#endif /* !G_ENABLE_DEBUG */
++
++
++/* VOID:OBJECT,OBJECT (e-map-marshal.list:1) */
++void
++g_cclosure_user_marshal_VOID__OBJECT_OBJECT (GClosure *closure,
++ GValue *return_value,
++ guint n_param_values,
++ const GValue *param_values,
++ gpointer invocation_hint,
++ gpointer marshal_data)
++{
++ typedef void (*GMarshalFunc_VOID__OBJECT_OBJECT) (gpointer data1,
++ gpointer arg_1,
++ gpointer arg_2,
++ gpointer data2);
++ register GMarshalFunc_VOID__OBJECT_OBJECT callback;
++ register GCClosure *cc = (GCClosure*) closure;
++ register gpointer data1, data2;
++
++ g_return_if_fail (n_param_values == 3);
++
++ if (G_CCLOSURE_SWAP_DATA (closure))
++ {
++ data1 = closure->data;
++ data2 = g_value_peek_pointer (param_values + 0);
++ }
++ else
++ {
++ data1 = g_value_peek_pointer (param_values + 0);
++ data2 = closure->data;
++ }
++ callback = (GMarshalFunc_VOID__OBJECT_OBJECT) (marshal_data ? marshal_data : cc->callback);
++
++ callback (data1,
++ g_marshal_value_peek_object (param_values + 1),
++ g_marshal_value_peek_object (param_values + 2),
++ data2);
++}
++
+diff -Nrup gnome-panel-2.14.1/applets/clock/e-map/e-map-marshal.h ../gnome-panel-2.14.1/applets/clock/e-map/e-map-marshal.h
+--- gnome-panel-2.14.1/applets/clock/e-map/e-map-marshal.h 1970-01-01 01:00:00.000000000 +0100
++++ ../gnome-panel-2.14.1/applets/clock/e-map/e-map-marshal.h 2006-06-12 16:18:42.529818000 +0200
+@@ -0,0 +1,20 @@
++
++#ifndef __g_cclosure_user_marshal_MARSHAL_H__
++#define __g_cclosure_user_marshal_MARSHAL_H__
++
++#include <glib-object.h>
++
++G_BEGIN_DECLS
++
++/* VOID:OBJECT,OBJECT (e-map-marshal.list:1) */
++extern void g_cclosure_user_marshal_VOID__OBJECT_OBJECT (GClosure *closure,
++ GValue *return_value,
++ guint n_param_values,
++ const GValue *param_values,
++ gpointer invocation_hint,
++ gpointer marshal_data);
++
++G_END_DECLS
++
++#endif /* __g_cclosure_user_marshal_MARSHAL_H__ */
++
+diff -Nrup gnome-panel-2.14.1/applets/clock/e-map/e-map-marshal.list ../gnome-panel-2.14.1/applets/clock/e-map/e-map-marshal.list
+--- gnome-panel-2.14.1/applets/clock/e-map/e-map-marshal.list 1970-01-01 01:00:00.000000000 +0100
++++ ../gnome-panel-2.14.1/applets/clock/e-map/e-map-marshal.list 2006-06-12 16:18:42.525751000 +0200
+@@ -0,0 +1 @@
++VOID:OBJECT,OBJECT
+diff -Nrup gnome-panel-2.14.1/applets/clock/e-map/e-map.c ../gnome-panel-2.14.1/applets/clock/e-map/e-map.c
+--- gnome-panel-2.14.1/applets/clock/e-map/e-map.c 1970-01-01 01:00:00.000000000 +0100
++++ ../gnome-panel-2.14.1/applets/clock/e-map/e-map.c 2006-06-12 16:18:42.527048000 +0200
+@@ -0,0 +1,1789 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++/* Map widget.
++ *
++ * Copyright (C) 2000-2001 Ximian, Inc.
++ *
++ * Authors: Hans Petter Jansson <[email protected]>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of version 2 of the GNU General Public
++ * License as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public
++ * License along with this program; if not, write to the
++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++ * Boston, MA 02111-1307, USA.
++ */
++
++#include <config.h>
++#include <math.h>
++#include <stdlib.h>
++#include <gdk/gdkkeysyms.h>
++#include <gtk/gtksignal.h>
++#include <gdk-pixbuf/gdk-pixbuf.h>
++#include <libart_lgpl/art_filterlevel.h>
++
++#include "e-map.h"
++
++/* Scroll step increment */
++
++#define SCROLL_STEP_SIZE 32
++
++
++/* */
++
++#define E_MAP_GET_WIDTH(map) gdk_pixbuf_get_width(((EMapPrivate *) E_MAP(map)->priv)->map_render_pixbuf)
++#define E_MAP_GET_HEIGHT(map) gdk_pixbuf_get_height(((EMapPrivate *) E_MAP(map)->priv)->map_render_pixbuf)
++
++
++/* Zoom state - keeps track of animation hacks */
++
++typedef enum
++{
++ E_MAP_ZOOMED_IN,
++ E_MAP_ZOOMED_OUT,
++ E_MAP_ZOOMING_IN,
++ E_MAP_ZOOMING_OUT
++}
++EMapZoomState;
++
++
++/* Private part of the EMap structure */
++
++typedef struct
++{
++ /* Pointer to map image */
++ GdkPixbuf *map_pixbuf, *map_render_pixbuf;
++
++ /* Settings */
++ gboolean frozen, smooth_zoom;
++
++ /* Adjustments for scrolling */
++ GtkAdjustment *hadj;
++ GtkAdjustment *vadj;
++
++ /* Current scrolling offsets */
++ int xofs, yofs;
++
++ /* Realtime zoom data */
++ EMapZoomState zoom_state;
++ double zoom_target_long, zoom_target_lat;
++
++ /* Dots */
++ GPtrArray *points;
++}
++EMapPrivate;
++
++
++/* Internal prototypes */
++
++static void e_map_class_init (EMapClass *class);
++static void e_map_init (EMap *view);
++static void e_map_finalize (GObject *object);
++static void e_map_destroy (GtkObject *object);
++static void e_map_unmap (GtkWidget *widget);
++static void e_map_realize (GtkWidget *widget);
++static void e_map_unrealize (GtkWidget *widget);
++static void e_map_size_request (GtkWidget *widget, GtkRequisition *requisition);
++static void e_map_size_allocate (GtkWidget *widget, GtkAllocation *allocation);
++static gint e_map_button_press (GtkWidget *widget, GdkEventButton *event);
++static gint e_map_button_release (GtkWidget *widget, GdkEventButton *event);
++static gint e_map_motion (GtkWidget *widget, GdkEventMotion *event);
++static gint e_map_expose (GtkWidget *widget, GdkEventExpose *event);
++static gint e_map_key_press (GtkWidget *widget, GdkEventKey *event);
++static void e_map_set_scroll_adjustments (GtkWidget *widget, GtkAdjustment *hadj, GtkAdjustment *vadj);
++
++static void update_render_pixbuf (EMap *map, ArtFilterLevel interp, gboolean render_overlays);
++static void set_scroll_area (EMap *view);
++static void request_paint_area (EMap *view, GdkRectangle *area);
++static void center_at (EMap *map, int x, int y, gboolean scroll);
++static void smooth_center_at (EMap *map, int x, int y);
++static void scroll_to (EMap *view, int x, int y);
++static void zoom_do (EMap *map);
++static gint load_map_background (EMap *view, gchar *name);
++static void adjustment_changed_cb (GtkAdjustment *adj, gpointer data);
++static void update_and_paint (EMap *map);
++static void update_render_point (EMap *map, EMapPoint *point);
++static void repaint_point (EMap *map, EMapPoint *point);
++
++static GtkWidgetClass *parent_class;
++
++
++/* ----------------- *
++ * Widget management *
++ * ----------------- */
++
++
++/**
++ * e_map_get_type:
++ * @void:
++ *
++ * Registers the #EMap class if necessary, and returns the type ID
++ * associated to it.
++ *
++ * Return value: The type ID of the #EMap class.
++ **/
++
++GtkType
++e_map_get_type (void)
++{
++ static GtkType e_map_type = 0;
++
++ if (!e_map_type)
++ {
++ static const GtkTypeInfo e_map_info =
++ {
++ "EMap",
++ sizeof (EMap),
++ sizeof (EMapClass),
++ (GtkClassInitFunc) e_map_class_init,
++ (GtkObjectInitFunc) e_map_init,
++ NULL, /* reserved_1 */
++ NULL, /* reserved_2 */
++ (GtkClassInitFunc) NULL
++ };
++
++ e_map_type = gtk_type_unique (GTK_TYPE_WIDGET, &e_map_info);
++ }
++
++ return e_map_type;
++}
++
++/* Class initialization function for the map view */
++
++static void
++e_map_class_init (EMapClass *class)
++{
++ GObjectClass *gobject_class;
++ GtkObjectClass *object_class;
++ GtkWidgetClass *widget_class;
++
++ gobject_class = (GObjectClass *) class;
++ object_class = (GtkObjectClass *) class;
++ widget_class = (GtkWidgetClass *) class;
++
++ parent_class = g_type_class_ref(GTK_TYPE_WIDGET);
++
++ gobject_class->finalize = e_map_finalize;
++
++ object_class->destroy = e_map_destroy;
++
++ class->set_scroll_adjustments = e_map_set_scroll_adjustments;
++ widget_class->set_scroll_adjustments_signal = gtk_signal_new ("set_scroll_adjustments",
++ GTK_RUN_LAST,
++ GTK_CLASS_TYPE (object_class),
++ G_STRUCT_OFFSET (EMapClass, set_scroll_adjustments),
++ gtk_marshal_NONE__POINTER_POINTER,
++ GTK_TYPE_NONE, 2,
++ GTK_TYPE_ADJUSTMENT,
++ GTK_TYPE_ADJUSTMENT);
++
++ widget_class->unmap = e_map_unmap;
++ widget_class->realize = e_map_realize;
++ widget_class->unrealize = e_map_unrealize;
++ widget_class->size_request = e_map_size_request;
++ widget_class->size_allocate = e_map_size_allocate;
++ widget_class->button_press_event = e_map_button_press;
++ widget_class->button_release_event = e_map_button_release;
++ widget_class->motion_notify_event = e_map_motion;
++ widget_class->expose_event = e_map_expose;
++ widget_class->key_press_event = e_map_key_press;
++}
++
++
++/* Object initialization function for the map view */
++
++static void
++e_map_init (EMap *view)
++{
++ EMapPrivate *priv;
++
++ priv = g_new0 (EMapPrivate, 1);
++ view->priv = priv;
++
++ load_map_background (view, PACKAGE_DATA_DIR"/world_map-960.png");
++ priv->frozen = FALSE;
++ priv->smooth_zoom = TRUE;
++ priv->zoom_state = E_MAP_ZOOMED_OUT;
++ priv->points = g_ptr_array_new ();
++
++ GTK_WIDGET_SET_FLAGS (view, GTK_CAN_FOCUS);
++ GTK_WIDGET_UNSET_FLAGS (view, GTK_NO_WINDOW);
++}
++
++
++/* Destroy handler for the map view */
++
++static void
++e_map_destroy (GtkObject *object)
++{
++ EMap *view;
++ EMapPrivate *priv;
++
++ g_return_if_fail (object != NULL);
++ g_return_if_fail (IS_E_MAP (object));
++
++ view = E_MAP (object);
++ priv = view->priv;
++
++ g_signal_handlers_disconnect_by_func (priv->hadj, adjustment_changed_cb, view);
++ g_signal_handlers_disconnect_by_func (priv->vadj, adjustment_changed_cb, view);
++
++ if (GTK_OBJECT_CLASS (parent_class)->destroy)
++ (*GTK_OBJECT_CLASS (parent_class)->destroy) (object);
++}
++
++
++/* Finalize handler for the map view */
++
++static void
++e_map_finalize (GObject *object)
++{
++ EMap *view;
++ EMapPrivate *priv;
++
++ g_return_if_fail (object != NULL);
++ g_return_if_fail (IS_E_MAP (object));
++
++ view = E_MAP (object);
++ priv = view->priv;
++
++ g_object_unref((priv->hadj));
++ priv->hadj = NULL;
++
++ g_object_unref((priv->vadj));
++ priv->vadj = NULL;
++
++ if (priv->map_pixbuf)
++ {
++ g_object_unref (priv->map_pixbuf);
++ priv->map_pixbuf = NULL;
++ }
++
++ if (priv->map_render_pixbuf)
++ {
++ g_object_unref (priv->map_render_pixbuf);
++ priv->map_render_pixbuf = NULL;
++ }
++
++ g_free (priv);
++ view->priv = NULL;
++
++ if (G_OBJECT_CLASS (parent_class)->finalize)
++ (*G_OBJECT_CLASS (parent_class)->finalize) (object);
++}
++
++
++/* Unmap handler for the map view */
++
++static void
++e_map_unmap (GtkWidget *widget)
++{
++ g_return_if_fail (widget != NULL);
++ g_return_if_fail (IS_E_MAP (widget));
++
++ if (GTK_WIDGET_CLASS (parent_class)->unmap)
++ (*GTK_WIDGET_CLASS (parent_class)->unmap) (widget);
++}
++
++
++/* Realize handler for the map view */
++
++static void
++e_map_realize (GtkWidget *widget)
++{
++ GdkWindowAttr attr;
++ int attr_mask;
++
++ g_return_if_fail (widget != NULL);
++ g_return_if_fail (IS_E_MAP (widget));
++
++ GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
++
++ attr.window_type = GDK_WINDOW_CHILD;
++ attr.x = widget->allocation.x;
++ attr.y = widget->allocation.y;
++ attr.width = widget->allocation.width;
++ attr.height = widget->allocation.height;
++ attr.wclass = GDK_INPUT_OUTPUT;
++ attr.visual = gdk_rgb_get_visual ();
++ attr.colormap = gdk_rgb_get_cmap ();
++ attr.event_mask = gtk_widget_get_events (widget) |
++ GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_KEY_PRESS_MASK |
++ GDK_POINTER_MOTION_MASK;
++
++ attr_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
++
++ widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attr, attr_mask);
++ gdk_window_set_user_data (widget->window, widget);
++
++ widget->style = gtk_style_attach (widget->style, widget->window);
++
++ gdk_window_set_back_pixmap (widget->window, NULL, FALSE);
++ update_render_pixbuf (E_MAP (widget), GDK_INTERP_BILINEAR, TRUE);
++}
++
++
++/* Unrealize handler for the map view */
++
++static void
++e_map_unrealize (GtkWidget *widget)
++{
++ g_return_if_fail (widget != NULL);
++ g_return_if_fail (IS_E_MAP (widget));
++
++ if (GTK_WIDGET_CLASS (parent_class)->unrealize)
++ (*GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
++}
++
++
++/* Size_request handler for the map view */
++
++static void
++e_map_size_request (GtkWidget *widget, GtkRequisition *requisition)
++{
++ EMap *view;
++ EMapPrivate *priv;
++
++ g_return_if_fail (widget != NULL);
++ g_return_if_fail (IS_E_MAP (widget));
++ g_return_if_fail (requisition != NULL);
++
++ view = E_MAP (widget);
++ priv = view->priv;
++
++ /* TODO: Put real sizes here. */
++
++ requisition->width = gdk_pixbuf_get_width (priv->map_pixbuf);
++ requisition->height = gdk_pixbuf_get_height (priv->map_pixbuf);
++}
++
++
++/* Size_allocate handler for the map view */
++
++static void
++e_map_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
++{
++ EMap *view;
++ EMapPrivate *priv;
++ int xofs, yofs;
++ GdkRectangle area;
++
++ g_return_if_fail (widget != NULL);
++ g_return_if_fail (IS_E_MAP (widget));
++ g_return_if_fail (allocation != NULL);
++
++ view = E_MAP (widget);
++ priv = view->priv;
++
++ xofs = priv->xofs;
++ yofs = priv->yofs;
++
++ /* Resize the window */
++
++ widget->allocation = *allocation;
++
++ if (GTK_WIDGET_REALIZED (widget))
++ {
++ gdk_window_move_resize (widget->window, allocation->x, allocation->y, allocation->width, allocation->height);
++
++ area.x = 0;
++ area.y = 0;
++ area.width = allocation->width;
++ area.height = allocation->height;
++ request_paint_area (E_MAP (widget), &area);
++ }
++
++ update_render_pixbuf (view, GDK_INTERP_BILINEAR, TRUE);
++}
++
++
++/* Button press handler for the map view */
++
++static gint
++e_map_button_press (GtkWidget *widget, GdkEventButton *event)
++{
++ EMap *view;
++ EMapPrivate *priv;
++
++ view = E_MAP (widget);
++ priv = view->priv;
++
++ if (!GTK_WIDGET_HAS_FOCUS (widget)) gtk_widget_grab_focus (widget);
++ return TRUE;
++}
++
++
++/* Button release handler for the map view */
++
++static gint
++e_map_button_release (GtkWidget *widget, GdkEventButton *event)
++{
++ EMap *view;
++ EMapPrivate *priv;
++
++ view = E_MAP (widget);
++ priv = view->priv;
++
++ if (event->button != 1) return FALSE;
++
++ gdk_pointer_ungrab (event->time);
++ return TRUE;
++}
++
++
++/* Motion handler for the map view */
++
++static gint
++e_map_motion (GtkWidget *widget, GdkEventMotion *event)
++{
++ EMap *view;
++ EMapPrivate *priv;
++
++ view = E_MAP (widget);
++ priv = view->priv;
++
++ return FALSE;
++
++/*
++ * if (event->is_hint)
++ * gdk_window_get_pointer(widget->window, &x, &y, &mods);
++ * else
++ * {
++ * x = event->x;
++ * y = event->y;
++ * }
++ *
++ * return TRUE;
++ */
++}
++
++
++/* Expose handler for the map view */
++
++static gint
++e_map_expose (GtkWidget *widget, GdkEventExpose *event)
++{
++ EMap *view;
++
++ g_return_val_if_fail (widget != NULL, FALSE);
++ g_return_val_if_fail (IS_E_MAP (widget), FALSE);
++ g_return_val_if_fail (event != NULL, FALSE);
++
++ view = E_MAP (widget);
++
++ request_paint_area (view, &event->area);
++ return TRUE;
++}
++
++
++/* Set_scroll_adjustments handler for the map view */
++
++static void
++e_map_set_scroll_adjustments (GtkWidget *widget, GtkAdjustment *hadj, GtkAdjustment *vadj)
++{
++ EMap *view;
++ EMapPrivate *priv;
++ gboolean need_adjust;
++
++ g_return_if_fail (widget != NULL);
++ g_return_if_fail (IS_E_MAP (widget));
++
++ view = E_MAP (widget);
++ priv = view->priv;
++
++ if (hadj) g_return_if_fail (GTK_IS_ADJUSTMENT (hadj));
++ else hadj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
++
++ if (vadj) g_return_if_fail (GTK_IS_ADJUSTMENT (vadj));
++ else vadj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
++
++ if (priv->hadj && priv->hadj != hadj)
++ {
++ g_signal_handlers_disconnect_by_func (priv->hadj,
++ adjustment_changed_cb,
++ view);
++ g_object_unref (priv->hadj);
++ }
++
++ if (priv->vadj && priv->vadj != vadj)
++ {
++ g_signal_handlers_disconnect_by_func (priv->vadj,
++ adjustment_changed_cb,
++ view);
++ g_object_unref (priv->vadj);
++ }
++
++ need_adjust = FALSE;
++
++ if (priv->hadj != hadj)
++ {
++ priv->hadj = hadj;
++ g_object_ref (priv->hadj);
++ gtk_object_sink (GTK_OBJECT (priv->hadj));
++
++ g_signal_connect (priv->hadj, "value_changed",
++ G_CALLBACK (adjustment_changed_cb), view);
++
++ need_adjust = TRUE;
++ }
++
++ if (priv->vadj != vadj)
++ {
++ priv->vadj = vadj;
++ g_object_ref (priv->vadj);
++ gtk_object_sink (GTK_OBJECT (priv->vadj));
++
++ g_signal_connect (priv->vadj, "value_changed",
++ G_CALLBACK (adjustment_changed_cb), view);
++
++ need_adjust = TRUE;
++ }
++
++ if (need_adjust) adjustment_changed_cb (NULL, view);
++}
++
++
++/* Key press handler for the map view */
++
++static gint
++e_map_key_press (GtkWidget *widget, GdkEventKey *event)
++{
++ EMap *view;
++ EMapPrivate *priv;
++ gboolean do_scroll;
++ int xofs, yofs;
++
++ view = E_MAP (widget);
++ priv = view->priv;
++
++ do_scroll = FALSE;
++ xofs = yofs = 0;
++
++ switch (event->keyval)
++ {
++ case GDK_Up:
++ do_scroll = TRUE;
++ xofs = 0;
++ yofs = -SCROLL_STEP_SIZE;
++ break;
++
++ case GDK_Down:
++ do_scroll = TRUE;
++ xofs = 0;
++ yofs = SCROLL_STEP_SIZE;
++ break;
++
++ case GDK_Left:
++ do_scroll = TRUE;
++ xofs = -SCROLL_STEP_SIZE;
++ yofs = 0;
++ break;
++
++ case GDK_Right:
++ do_scroll = TRUE;
++ xofs = SCROLL_STEP_SIZE;
++ yofs = 0;
++ break;
++
++ default:
++ return FALSE;
++ }
++
++ if (do_scroll)
++ {
++ int x, y;
++
++ x = CLAMP (priv->xofs + xofs, 0, priv->hadj->upper - priv->hadj->page_size);
++ y = CLAMP (priv->yofs + yofs, 0, priv->vadj->upper - priv->vadj->page_size);
++
++ scroll_to (view, x, y);
++
++ gtk_signal_handler_block_by_data (GTK_OBJECT (priv->hadj), view);
++ gtk_signal_handler_block_by_data (GTK_OBJECT (priv->vadj), view);
++
++ priv->hadj->value = x;
++ priv->vadj->value = y;
++
++ gtk_signal_emit_by_name (GTK_OBJECT (priv->hadj), "value_changed");
++ gtk_signal_emit_by_name (GTK_OBJECT (priv->vadj), "value_changed");
++
++ gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->hadj), view);
++ gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->vadj), view);
++ }
++
++ return TRUE;
++}
++
++
++/* ---------------- *
++ * Widget interface *
++ * ---------------- */
++
++
++/**
++ * e_map_new:
++ * @void:
++ *
++ * Creates a new empty map widget.
++ *
++ * Return value: A newly-created map widget.
++ **/
++
++EMap *
++e_map_new ()
++{
++ GtkWidget *widget;
++
++ widget = GTK_WIDGET (gtk_type_new (TYPE_E_MAP));
++ return (E_MAP (widget));
++}
++
++
++/* --- Coordinate translation --- */
++
++
++/* These functions translate coordinates between longitude/latitude and
++ * the image x/y offsets, using the equidistant cylindrical projection.
++ *
++ * Longitude E <-180, 180]
++ * Latitude E <-90, 90] */
++
++void
++e_map_window_to_world (EMap *map, double win_x, double win_y, double *world_longitude, double *world_latitude)
++{
++ EMapPrivate *priv;
++ int width, height;
++
++ g_return_if_fail (map);
++
++ priv = map->priv;
++ g_return_if_fail (GTK_WIDGET_REALIZED (GTK_WIDGET (map)));
++
++ width = gdk_pixbuf_get_width (priv->map_render_pixbuf);
++ height = gdk_pixbuf_get_height (priv->map_render_pixbuf);
++
++ *world_longitude = (win_x + priv->xofs - (double) width / 2.0) /
++ ((double) width / 2.0) * 180.0;
++ *world_latitude = ((double) height / 2.0 - win_y - priv->yofs) /
++ ((double) height / 2.0) * 90.0;
++}
++
++
++void
++e_map_world_to_window (EMap *map, double world_longitude, double world_latitude, double *win_x, double *win_y)
++{
++ EMapPrivate *priv;
++ int width, height;
++
++ g_return_if_fail (map);
++
++ priv = map->priv;
++ g_return_if_fail (priv->map_render_pixbuf);
++ g_return_if_fail (world_longitude >= -180.0 && world_longitude <= 180.0);
++ g_return_if_fail (world_latitude >= -90.0 && world_latitude <= 90.0);
++
++ width = gdk_pixbuf_get_width (priv->map_render_pixbuf);
++ height = gdk_pixbuf_get_height (priv->map_render_pixbuf);
++
++ *win_x = (width / 2.0 + (width / 2.0) * world_longitude / 180.0) - priv->xofs;
++ *win_y = (height / 2.0 - (height / 2.0) * world_latitude / 90.0) - priv->yofs;
++
++#ifdef DEBUG
++ printf ("Map size: (%d, %d)\nCoords: (%.1f, %.1f) -> (%.1f, %.1f)\n---\n", width, height, world_longitude, world_latitude, *win_x, *win_y);
++#endif
++}
++
++
++/* --- Zoom --- */
++
++
++double
++e_map_get_magnification (EMap *map)
++{
++ EMapPrivate *priv;
++
++ priv = map->priv;
++ if (priv->zoom_state == E_MAP_ZOOMED_IN) return 2.0;
++ else return 1.0;
++}
++
++
++void
++e_map_zoom_to_location (EMap *map, double longitude, double latitude)
++{
++ EMapPrivate *priv;
++ int width, height;
++
++ g_return_if_fail (map);
++ g_return_if_fail (GTK_WIDGET_REALIZED (GTK_WIDGET (map)));
++
++ priv = map->priv;
++
++ if (priv->zoom_state == E_MAP_ZOOMED_IN) e_map_zoom_out (map);
++ else if (priv->zoom_state != E_MAP_ZOOMED_OUT) return;
++
++ width = gdk_pixbuf_get_width (priv->map_render_pixbuf);
++ height = gdk_pixbuf_get_height (priv->map_render_pixbuf);
++
++ priv->zoom_state = E_MAP_ZOOMING_IN;
++ priv->zoom_target_long = longitude;
++ priv->zoom_target_lat = latitude;
++
++ zoom_do (map);
++}
++
++
++void
++e_map_zoom_out (EMap *map)
++{
++ EMapPrivate *priv;
++ int width, height;
++
++ g_return_if_fail (map);
++ g_return_if_fail (GTK_WIDGET_REALIZED (GTK_WIDGET (map)));
++
++ priv = map->priv;
++
++ if (priv->zoom_state != E_MAP_ZOOMED_IN) return;
++
++ width = gdk_pixbuf_get_width (priv->map_render_pixbuf);
++ height = gdk_pixbuf_get_height (priv->map_render_pixbuf);
++
++ priv->zoom_state = E_MAP_ZOOMING_OUT;
++ zoom_do (map);
++ priv->zoom_state = E_MAP_ZOOMED_OUT;
++}
++
++
++void
++e_map_set_smooth_zoom (EMap *map, gboolean state)
++{
++ ((EMapPrivate *) map->priv)->smooth_zoom = state;
++}
++
++
++gboolean
++e_map_get_smooth_zoom (EMap *map)
++{
++ return (((EMapPrivate *) map->priv)->smooth_zoom);
++}
++
++
++void
++e_map_freeze (EMap *map)
++{
++ ((EMapPrivate *) map->priv)->frozen = TRUE;
++}
++
++
++void
++e_map_thaw (EMap *map)
++{
++ ((EMapPrivate *) map->priv)->frozen = FALSE;
++ update_and_paint (map);
++}
++
++
++/* --- Point manipulation --- */
++
++
++EMapPoint *
++e_map_add_point (EMap *map, gchar *name, double longitude, double latitude, guint32 color_rgba)
++{
++ EMapPrivate *priv;
++ EMapPoint *point;
++
++ priv = map->priv;
++ point = g_new0 (EMapPoint, 1);
++
++ point->name = name; /* Can be NULL */
++ point->longitude = longitude;
++ point->latitude = latitude;
++ point->rgba = color_rgba;
++
++ g_ptr_array_add (priv->points, (gpointer) point);
++
++ if (!priv->frozen)
++ {
++ update_render_point (map, point);
++ repaint_point (map, point);
++ }
++
++ return point;
++}
++
++
++void
++e_map_remove_point (EMap *map, EMapPoint *point)
++{
++ EMapPrivate *priv;
++
++ priv = map->priv;
++ g_ptr_array_remove (priv->points, point);
++
++ if (!((EMapPrivate *) map->priv)->frozen)
++ {
++ /* FIXME: Re-scaling the whole pixbuf is more than a little
++ * overkill when just one point is removed */
++
++ update_render_pixbuf (map, GDK_INTERP_BILINEAR, TRUE);
++ repaint_point (map, point);
++ }
++
++ g_free (point);
++}
++
++
++void
++e_map_point_get_location (EMapPoint *point, double *longitude, double *latitude)
++{
++ *longitude = point->longitude;
++ *latitude = point->latitude;
++}
++
++
++gchar *
++e_map_point_get_name (EMapPoint *point)
++{
++ return point->name;
++}
++
++
++guint32
++e_map_point_get_color_rgba (EMapPoint *point)
++{
++ return point->rgba;
++}
++
++
++void
++e_map_point_set_color_rgba (EMap *map, EMapPoint *point, guint32 color_rgba)
++{
++ point->rgba = color_rgba;
++
++ if (!((EMapPrivate *) map->priv)->frozen)
++ {
++ /* TODO: Redraw area around point only */
++
++ update_render_point (map, point);
++ repaint_point (map, point);
++ }
++}
++
++
++void
++e_map_point_set_data (EMapPoint *point, gpointer data)
++{
++ point->user_data = data;
++}
++
++
++gpointer
++e_map_point_get_data (EMapPoint *point)
++{
++ return point->user_data;
++}
++
++
++gboolean
++e_map_point_is_in_view (EMap *map, EMapPoint *point)
++{
++ EMapPrivate *priv;
++ double x, y;
++
++ priv = map->priv;
++ if (!priv->map_render_pixbuf) return FALSE;
++
++ e_map_world_to_window (map, point->longitude, point->latitude, &x, &y);
++
++ if (x >= 0 && x < GTK_WIDGET (map)->allocation.width &&
++ y >= 0 && y < GTK_WIDGET (map)->allocation.height)
++ return TRUE;
++
++ return FALSE;
++}
++
++
++EMapPoint *
++e_map_get_closest_point (EMap *map, double longitude, double latitude, gboolean in_view)
++{
++ EMapPrivate *priv;
++ EMapPoint *point_chosen = NULL, *point;
++ double min_dist = 0.0, dist;
++ double dx, dy;
++ int i;
++
++ priv = map->priv;
++
++ for (i = 0; i < priv->points->len; i++)
++ {
++ point = g_ptr_array_index (priv->points, i);
++ if (in_view && !e_map_point_is_in_view (map, point)) continue;
++
++ dx = point->longitude - longitude;
++ dy = point->latitude - latitude;
++ dist = dx * dx + dy * dy;
++
++ if (!point_chosen || dist < min_dist)
++ {
++ min_dist = dist;
++ point_chosen = point;
++ }
++ }
++
++ return point_chosen;
++}
++
++
++/* ------------------ *
++ * Internal functions *
++ * ------------------ */
++
++
++static void
++repaint_visible (EMap *map)
++{
++ GdkRectangle area;
++
++ area.x = 0;
++ area.y = 0;
++ area.width = GTK_WIDGET (map)->allocation.width;
++ area.height = GTK_WIDGET (map)->allocation.height;
++
++ request_paint_area (map, &area);
++}
++
++
++static void
++update_and_paint (EMap *map)
++{
++ update_render_pixbuf (map, GDK_INTERP_BILINEAR, TRUE);
++ repaint_visible (map);
++}
++
++
++static gint
++load_map_background (EMap *view, gchar *name)
++{
++ EMapPrivate *priv;
++ GdkPixbuf *pb0;
++
++ priv = view->priv;
++
++ pb0 = gdk_pixbuf_new_from_file (name, NULL);
++ if (!pb0)
++ return FALSE;
++
++ if (priv->map_pixbuf) g_object_unref (priv->map_pixbuf);
++ priv->map_pixbuf = pb0;
++ update_render_pixbuf (view, GDK_INTERP_BILINEAR, TRUE);
++
++ return TRUE;
++}
++
++
++static void
++update_render_pixbuf (EMap *map, ArtFilterLevel interp, gboolean render_overlays)
++{
++ EMapPrivate *priv;
++ EMapPoint *point;
++ int width, height, orig_width, orig_height;
++ double zoom;
++ int i;
++
++ if (!GTK_WIDGET_REALIZED (GTK_WIDGET (map))) return;
++
++ /* Set up value shortcuts */
++
++ priv = map->priv;
++ width = GTK_WIDGET (map)->allocation.width;
++ height = GTK_WIDGET (map)->allocation.height;
++ orig_width = gdk_pixbuf_get_width (priv->map_pixbuf);
++ orig_height = gdk_pixbuf_get_height (priv->map_pixbuf);
++
++ /* Compute scaled width and height based on the extreme dimension */
++
++ if ((double) width / orig_width > (double) height / orig_height)
++ {
++ zoom = (double) width / (double) orig_width;
++ }
++ else
++ {
++ zoom = (double) height / (double) orig_height;
++ }
++
++ if (priv->zoom_state == E_MAP_ZOOMED_IN) zoom *= 2.0;
++ height = (orig_height * zoom) + 0.5;
++ width = (orig_width * zoom) + 0.5;
++
++ /* Reallocate the pixbuf */
++
++ if (priv->map_render_pixbuf) g_object_unref (priv->map_render_pixbuf);
++ priv->map_render_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, /* No alpha */
++ 8, width, height);
++
++ /* Scale the original map into the rendering pixbuf */
++
++ if (width > 1 && height > 1)
++ {
++ gdk_pixbuf_scale (priv->map_pixbuf, priv->map_render_pixbuf, 0, 0, /* Dest (x, y) */
++ width, height, 0, 0, /* Offset (x, y) */
++ zoom, zoom, /* Scale (x, y) */
++ interp);
++ }
++
++ if (render_overlays)
++ {
++ /* Add points */
++
++ for (i = 0; i < priv->points->len; i++)
++ {
++ point = g_ptr_array_index (priv->points, i);
++ update_render_point (map, point);
++ }
++ }
++
++ /* Compute image offsets with respect to window */
++
++ set_scroll_area (map);
++}
++
++
++/* Queues a repaint of the specified area in window coordinates */
++
++static void
++request_paint_area (EMap *view, GdkRectangle *area)
++{
++ EMapPrivate *priv;
++ int width, height;
++
++ if (!GTK_WIDGET_DRAWABLE (GTK_WIDGET (view)) ||
++ !GTK_WIDGET_REALIZED (GTK_WIDGET (view))) return;
++
++ priv = view->priv;
++ if (!priv->map_render_pixbuf) return;
++
++ width = MIN (area->width, E_MAP_GET_WIDTH (view));
++ height = MIN (area->height, E_MAP_GET_HEIGHT (view));
++
++ /* This satisfies paranoia. To be removed */
++
++ if (priv->xofs + width > gdk_pixbuf_get_width (priv->map_render_pixbuf))
++ width = gdk_pixbuf_get_width (priv->map_render_pixbuf) - priv->xofs;
++
++ if (priv->yofs + height > gdk_pixbuf_get_height (priv->map_render_pixbuf))
++ height = gdk_pixbuf_get_height (priv->map_render_pixbuf) - priv->yofs;
++
++ /* We rely on the fast case always being the case, since we load and
++ * preprocess the source pixbuf ourselves */
++
++ if (gdk_pixbuf_get_colorspace (priv->map_render_pixbuf) == GDK_COLORSPACE_RGB && !gdk_pixbuf_get_has_alpha (priv->map_render_pixbuf) &&
++ gdk_pixbuf_get_bits_per_sample (priv->map_render_pixbuf) == 8)
++ {
++ guchar *pixels;
++ int rowstride;
++
++ rowstride = gdk_pixbuf_get_rowstride (priv->map_render_pixbuf);
++ pixels = gdk_pixbuf_get_pixels (priv->map_render_pixbuf) + (area->y + priv->yofs) * rowstride + 3 * (area->x + priv->xofs);
++ gdk_draw_rgb_image_dithalign (GTK_WIDGET (view)->window, GTK_WIDGET (view)->style->black_gc, area->x, area->y, width, height, GDK_RGB_DITHER_NORMAL, pixels, rowstride, 0, 0);
++ return;
++ }
++
++#ifdef DEBUG
++ g_print ("Doing hard redraw.\n");
++#endif
++}
++
++static void
++put_pixel_with_clipping (GdkPixbuf *pixbuf, gint x, gint y, guint rgba)
++{
++ gint width, height;
++ gint rowstride, n_channels;
++ guchar *pixels, *pixel;
++
++ width = gdk_pixbuf_get_width (pixbuf);
++ height = gdk_pixbuf_get_height (pixbuf);
++ rowstride = gdk_pixbuf_get_rowstride (pixbuf);
++ n_channels = gdk_pixbuf_get_n_channels (pixbuf);
++ pixels = gdk_pixbuf_get_pixels (pixbuf);
++
++ if (x < 0 || x >= width || y < 0 || y >= height)
++ return;
++
++ pixel = pixels + (y * rowstride) + (x * n_channels);
++
++ *pixel = (rgba >> 24);
++ *(pixel + 1) = (rgba >> 16) & 0x000000ff;
++ *(pixel + 2) = (rgba >> 8) & 0x000000ff;
++
++ if (n_channels > 3)
++ {
++ *(pixel + 3) = rgba & 0x000000ff;
++ }
++}
++
++
++/* Redraw point in client pixbuf */
++
++static void
++update_render_point (EMap *map, EMapPoint *point)
++{
++ EMapPrivate *priv;
++ GdkPixbuf *pb;
++ int width, height;
++ double px, py;
++
++ priv = map->priv;
++ pb = priv->map_render_pixbuf;
++ if (!pb) return;
++
++ width = gdk_pixbuf_get_width (pb);
++ height = gdk_pixbuf_get_height (pb);
++
++ e_map_world_to_window (map, point->longitude, point->latitude, &px, &py);
++ px += priv->xofs;
++ py += priv->yofs;
++
++ put_pixel_with_clipping (pb, px, py, point->rgba);
++ put_pixel_with_clipping (pb, px - 1, py, point->rgba);
++ put_pixel_with_clipping (pb, px + 1, py, point->rgba);
++ put_pixel_with_clipping (pb, px, py - 1, point->rgba);
++ put_pixel_with_clipping (pb, px, py + 1, point->rgba);
++
++ put_pixel_with_clipping (pb, px - 2, py, 0x000000ff);
++ put_pixel_with_clipping (pb, px + 2, py, 0x000000ff);
++ put_pixel_with_clipping (pb, px, py - 2, 0x000000ff);
++ put_pixel_with_clipping (pb, px, py + 2, 0x000000ff);
++ put_pixel_with_clipping (pb, px - 1, py - 1, 0x000000ff);
++ put_pixel_with_clipping (pb, px - 1, py + 1, 0x000000ff);
++ put_pixel_with_clipping (pb, px + 1, py - 1, 0x000000ff);
++ put_pixel_with_clipping (pb, px + 1, py + 1, 0x000000ff);
++}
++
++
++/* Repaint point on X server */
++
++static void
++repaint_point (EMap *map, EMapPoint *point)
++{
++ EMapPrivate *priv;
++ GdkRectangle area;
++ double px, py;
++
++ if (!e_map_point_is_in_view (map, point)) return;
++ priv = map->priv;
++
++ e_map_world_to_window (map, point->longitude, point->latitude, &px, &py);
++
++ area.x = (int) px - 2;
++ area.y = (int) py - 2;
++ area.width = 5;
++ area.height = 5;
++ request_paint_area (map, &area);
++}
++
++
++static void
++center_at (EMap *map, int x, int y, gboolean scroll)
++{
++ EMapPrivate *priv;
++ int pb_width, pb_height,
++ view_width, view_height;
++
++ priv = map->priv;
++
++ pb_width = E_MAP_GET_WIDTH (map);
++ pb_height = E_MAP_GET_HEIGHT (map);
++
++ view_width = GTK_WIDGET (map)->allocation.width;
++ view_height = GTK_WIDGET (map)->allocation.height;
++
++ x = CLAMP (x - (view_width / 2), 0, pb_width - view_width);
++ y = CLAMP (y - (view_height / 2), 0, pb_height - view_height);
++
++ if (scroll) scroll_to (map, x, y);
++ else
++ {
++ priv->xofs = x;
++ priv->yofs = y;
++ }
++}
++
++
++static void
++smooth_center_at (EMap *map, int x, int y)
++{
++ EMapPrivate *priv;
++ int pb_width, pb_height,
++ view_width, view_height;
++ int dx, dy;
++
++ priv = map->priv;
++
++ pb_width = E_MAP_GET_WIDTH (map);
++ pb_height = E_MAP_GET_HEIGHT (map);
++
++ view_width = GTK_WIDGET (map)->allocation.width;
++ view_height = GTK_WIDGET (map)->allocation.height;
++
++ x = CLAMP (x - (view_width / 2), 0, pb_width - view_width);
++ y = CLAMP (y - (view_height / 2), 0, pb_height - view_height);
++
++ for (;;)
++ {
++ if (priv->xofs == x && priv->yofs == y) break;
++
++ dx = (x < priv->xofs) ? -1 : (x > priv->xofs) ? 1 : 0;
++ dy = (y < priv->yofs) ? -1 : (y > priv->yofs) ? 1 : 0;
++
++ scroll_to (map, priv->xofs + dx, priv->yofs + dy);
++ }
++}
++
++
++/* Scrolls the view to the specified offsets. Does not perform range checking! */
++
++static void
++scroll_to (EMap *view, int x, int y)
++{
++ EMapPrivate *priv;
++ int xofs, yofs;
++ GdkWindow *window;
++ GdkGC *gc;
++ int width, height;
++ int src_x, src_y;
++ int dest_x, dest_y;
++ GdkEvent *event;
++
++ priv = view->priv;
++
++ /* Compute offsets and check bounds */
++
++ xofs = x - priv->xofs;
++ yofs = y - priv->yofs;
++
++ if (xofs == 0 && yofs == 0) return;
++
++ priv->xofs = x;
++ priv->yofs = y;
++
++ if (!GTK_WIDGET_DRAWABLE (view)) return;
++
++ width = GTK_WIDGET (view)->allocation.width;
++ height = GTK_WIDGET (view)->allocation.height;
++
++ if (abs (xofs) >= width || abs (yofs) >= height)
++ {
++ GdkRectangle area;
++
++ area.x = 0;
++ area.y = 0;
++ area.width = width;
++ area.height = height;
++
++ request_paint_area (view, &area);
++ return;
++ }
++
++ window = GTK_WIDGET (view)->window;
++
++ /* Copy the window area */
++
++ src_x = xofs < 0 ? 0 : xofs;
++ src_y = yofs < 0 ? 0 : yofs;
++ dest_x = xofs < 0 ? -xofs : 0;
++ dest_y = yofs < 0 ? -yofs : 0;
++
++ gc = gdk_gc_new (window);
++ gdk_gc_set_exposures (gc, TRUE);
++
++ gdk_window_copy_area (window, gc, dest_x, dest_y, window, src_x, src_y, width - abs (xofs), height - abs (yofs));
++
++ gdk_gc_destroy (gc);
++
++ /* Add the scrolled-in region */
++
++ if (xofs)
++ {
++ GdkRectangle r;
++
++ r.x = xofs < 0 ? 0 : width - xofs;
++ r.y = 0;
++ r.width = abs (xofs);
++ r.height = height;
++
++ request_paint_area (view, &r);
++ }
++
++ if (yofs)
++ {
++ GdkRectangle r;
++
++ r.x = 0;
++ r.y = yofs < 0 ? 0 : height - yofs;
++ r.width = width;
++ r.height = abs (yofs);
++
++ request_paint_area (view, &r);
++ }
++
++ /* Process graphics exposures */
++
++ while ((event = gdk_event_get_graphics_expose (window)) != NULL)
++ {
++ gtk_widget_event (GTK_WIDGET (view), event);
++
++ if (event->expose.count == 0)
++ {
++ gdk_event_free (event);
++ break;
++ }
++
++ gdk_event_free (event);
++ }
++}
++
++
++static int divide_seq[] =
++{
++ /* Dividends for divisor of 2 */
++
++ -2,
++
++ 1,
++
++ /* Dividends for divisor of 4 */
++
++ -4,
++
++ 1, 3,
++
++ /* Dividends for divisor of 8 */
++
++ -8,
++
++ 1, 5, 3, 7,
++
++ /* Dividends for divisor of 16 */
++
++ -16,
++
++ 1, 9, 5, 13, 3, 11, 7, 15,
++
++ /* Dividends for divisor of 32 */
++
++ -32,
++
++ 1, 17, 9, 25, 5, 21, 13, 29, 3, 19,
++ 11, 27, 7, 23, 15, 31,
++
++ /* Dividends for divisor of 64 */
++
++ -64,
++
++ 1, 33, 17, 49, 9, 41, 25, 57, 5, 37,
++ 21, 53, 13, 45, 29, 61, 3, 35, 19, 51,
++ 11, 43, 27, 59, 7, 39, 23, 55, 15, 47,
++ 31, 63,
++
++ /* Dividends for divisor of 128 */
++
++ -128,
++
++ 1, 65, 33, 97, 17, 81, 49, 113, 9, 73,
++ 41, 105, 25, 89, 57, 121, 5, 69, 37, 101,
++ 21, 85, 53, 117, 13, 77, 45, 109, 29, 93,
++ 61, 125, 3, 67, 35, 99, 19, 83, 51, 115,
++ 11, 75, 43, 107, 27, 91, 59, 123, 7, 71,
++ 39, 103, 23, 87, 55, 119, 15, 79, 47, 111,
++ 31, 95, 63, 127,
++
++ /* Dividends for divisor of 256 */
++
++ -256,
++
++ 1, 129, 65, 193, 33, 161, 97, 225, 17, 145,
++ 81, 209, 49, 177, 113, 241, 9, 137, 73, 201,
++ 41, 169, 105, 233, 25, 153, 89, 217, 57, 185,
++ 121, 249, 5, 133, 69, 197, 37, 165, 101, 229,
++ 21, 149, 85, 213, 53, 181, 117, 245, 13, 141,
++ 77, 205, 45, 173, 109, 237, 29, 157, 93, 221,
++ 61, 189, 125, 253, 3, 131, 67, 195, 35, 163,
++ 99, 227, 19, 147, 83, 211, 51, 179, 115, 243,
++ 11, 139, 75, 203, 43, 171, 107, 235, 27, 155,
++ 91, 219, 59, 187, 123, 251, 7, 135, 71, 199,
++ 39, 167, 103, 231, 23, 151, 87, 215, 55, 183,
++ 119, 247, 15, 143, 79, 207, 47, 175, 111, 239,
++ 31, 159, 95, 223, 63, 191, 127, 255,
++
++ 0
++};
++
++
++typedef enum
++{
++ AXIS_X,
++ AXIS_Y
++}
++AxisType;
++
++
++static void
++blowup_window_area (GdkWindow *window, gint area_x, gint area_y, gint target_x, gint target_y, gint total_width, gint total_height, gfloat zoom_factor)
++{
++ GdkGC *gc;
++ AxisType strong_axis;
++ gfloat axis_factor, axis_counter;
++ gint zoom_chunk;
++ gint divisor_width = 0, divisor_height = 0;
++ gint divide_width_index, divide_height_index;
++ gint area_width, area_height;
++ gint i, j;
++ int line;
++
++
++ /* Set up the GC we'll be using */
++
++ gc = gdk_gc_new (window);
++ gdk_gc_set_exposures (gc, FALSE);
++
++ /* Get area constraints */
++
++ gdk_window_get_size (window, &area_width, &area_height);
++
++ /* Initialize area division array indexes */
++
++ divide_width_index = divide_height_index = 0;
++
++ /* Initialize axis counter */
++
++ axis_counter = 0.0;
++
++ /* Find the strong axis (which is the basis for iteration) and the ratio
++ * at which the other axis will be scaled.
++ *
++ * Also determine how many lines to expand in one fell swoop, and store
++ * this figure in zoom_chunk. */
++
++ if (area_width > area_height)
++ {
++ strong_axis = AXIS_X;
++ axis_factor = (double) area_height / (double) area_width;
++ zoom_chunk = MAX (1, area_width / 250);
++ i = (area_width * (zoom_factor - 1.0)) / zoom_chunk;
++ }
++ else
++ {
++ strong_axis = AXIS_Y;
++ axis_factor = (double) area_width / (double) area_height;
++ zoom_chunk = MAX (1, area_height / 250);
++ i = (area_height * (zoom_factor - 1.0)) / zoom_chunk;
++ }
++
++ /* Go, go, devil bunnies! Gogo devil bunnies! */
++
++ for (; i > 0; i--)
++ {
++ /* Reset division sequence table indexes as necessary */
++
++ if (!divide_seq[divide_width_index]) divide_width_index = 0;
++ if (!divide_seq[divide_height_index]) divide_height_index = 0;
++
++ /* Set new divisor if found in table */
++
++ if (divide_seq[divide_width_index] < 0)
++ divisor_width = abs (divide_seq[divide_width_index++]);
++ if (divide_seq[divide_height_index] < 0)
++ divisor_height = abs (divide_seq[divide_height_index++]);
++
++ /* Widen */
++
++ if (strong_axis == AXIS_X || axis_counter >= 1.0)
++ {
++ line = ((divide_seq[divide_width_index] * area_width) / divisor_width) + 0.5;
++
++ if ((line < target_x && target_x > area_width / 2) || (line > target_x && target_x > (area_width / 2) + zoom_chunk))
++ {
++ /* Push left */
++
++ for (j = 0; j < zoom_chunk - 1; j++)
++ gdk_window_copy_area (window, gc, line + j + 1, 0, window, line, 0, 1, area_height);
++
++ gdk_window_copy_area (window, gc, 0, 0, window, zoom_chunk, 0, line, area_height);
++ if (line > target_x) target_x -= zoom_chunk;
++ }
++ else
++ {
++ /* Push right */
++
++ for (j = 0; j < zoom_chunk - 1; j++)
++ gdk_window_copy_area (window, gc, line + j - (zoom_chunk - 1), 0, window, line - zoom_chunk, 0, 1, area_height);
++
++ gdk_window_copy_area (window, gc, line, 0, window, line - zoom_chunk, 0, area_width - line, area_height);
++ if (line < target_x) target_x += zoom_chunk;
++ }
++ }
++
++ if (strong_axis == AXIS_Y || axis_counter >= 1.0)
++ {
++ /* Heighten */
++
++ line = ((divide_seq[divide_height_index] * area_height) / divisor_height) + 0.5;
++
++ if ((line < target_y && target_y > area_height / 2) || (line > target_y && target_y > (area_height / 2) + zoom_chunk))
++ {
++ /* Push up */
++
++ for (j = 0; j < zoom_chunk - 1; j++)
++ gdk_window_copy_area (window, gc, 0, line + j + 1, window, 0, line, area_width, 1);
++
++ gdk_window_copy_area (window, gc, 0, 0, window, 0, zoom_chunk, area_width, line);
++ if (line > target_y) target_y -= zoom_chunk;
++ }
++ else
++ {
++ /* Push down */
++
++ for (j = 0; j < zoom_chunk - 1; j++)
++ gdk_window_copy_area (window, gc, 0, line + j - (zoom_chunk - 1), window, 0, line - zoom_chunk, area_width, 1);
++
++ gdk_window_copy_area (window, gc, 0, line, window, 0, line - zoom_chunk, area_width, area_height - line);
++ if (line < target_y) target_y += zoom_chunk;
++ }
++ }
++
++ divide_width_index++;
++ divide_height_index++;
++ if (axis_counter >= 1.0) axis_counter -= 1.0;
++ axis_counter += axis_factor;
++ }
++
++ /* Free our GC */
++
++ gdk_gc_destroy (gc);
++}
++
++
++static void
++zoom_in_smooth (EMap *map)
++{
++ GdkRectangle area;
++ EMapPrivate *priv;
++ GdkWindow *window;
++ int width, height;
++ int win_width, win_height;
++ int target_width, target_height;
++ double x, y;
++
++ g_return_if_fail (map);
++ g_return_if_fail (GTK_WIDGET_REALIZED (GTK_WIDGET (map)));
++
++ area.x = 0;
++ area.y = 0;
++ area.width = GTK_WIDGET (map)->allocation.width;
++ area.height = GTK_WIDGET (map)->allocation.height;
++
++ priv = map->priv;
++ window = GTK_WIDGET (map)->window;
++ width = gdk_pixbuf_get_width (priv->map_render_pixbuf);
++ height = gdk_pixbuf_get_height (priv->map_render_pixbuf);
++ win_width = GTK_WIDGET (map)->allocation.width;
++ win_height = GTK_WIDGET (map)->allocation.height;
++ target_width = win_width / 4;
++ target_height = win_height / 4;
++
++ /* Center the target point as much as possible */
++
++ e_map_world_to_window (map, priv->zoom_target_long, priv->zoom_target_lat, &x, &y);
++ smooth_center_at (map, x + priv->xofs, y + priv->yofs);
++
++ /* Render and paint a temporary map without overlays, so they don't get in
++ * the way (look ugly) while zooming */
++
++ update_render_pixbuf (map, GDK_INTERP_BILINEAR, FALSE);
++ request_paint_area (map, &area);
++
++ /* Find out where in the area we're going to zoom to */
++
++ e_map_world_to_window (map, priv->zoom_target_long, priv->zoom_target_lat, &x, &y);
++
++ /* Pre-render the zoomed-in map, so we can put it there quickly when the
++ * blowup sequence ends */
++
++ priv->zoom_state = E_MAP_ZOOMED_IN;
++ update_render_pixbuf (map, GDK_INTERP_BILINEAR, TRUE);
++
++ /* Do the blowup */
++
++ blowup_window_area (window, priv->xofs, priv->yofs, x, y, width, height, 1.68);
++
++ /* Set new scroll offsets and paint the zoomed map */
++
++ e_map_world_to_window (map, priv->zoom_target_long, priv->zoom_target_lat, &x, &y);
++ priv->xofs = CLAMP (priv->xofs + x - area.width / 2.0, 0, E_MAP_GET_WIDTH (map) - area.width);
++ priv->yofs = CLAMP (priv->yofs + y - area.height / 2.0, 0, E_MAP_GET_HEIGHT (map) - area.height);
++
++ request_paint_area (map, &area);
++}
++
++
++static void
++zoom_in (EMap *map)
++{
++ GdkRectangle area;
++ EMapPrivate *priv;
++ double x, y;
++
++ priv = map->priv;
++
++ area.x = 0;
++ area.y = 0;
++ area.width = GTK_WIDGET (map)->allocation.width;
++ area.height = GTK_WIDGET (map)->allocation.height;
++
++ priv->zoom_state = E_MAP_ZOOMED_IN;
++
++ update_render_pixbuf (map, GDK_INTERP_BILINEAR, TRUE);
++
++ e_map_world_to_window (map, priv->zoom_target_long, priv->zoom_target_lat, &x, &y);
++ priv->xofs = CLAMP (priv->xofs + x - area.width / 2.0, 0, E_MAP_GET_WIDTH (map) - area.width);
++ priv->yofs = CLAMP (priv->yofs + y - area.height / 2.0, 0, E_MAP_GET_HEIGHT (map) - area.height);
++
++ request_paint_area (map, &area);
++}
++
++
++static void
++zoom_out (EMap *map)
++{
++ GdkRectangle area;
++ EMapPrivate *priv;
++ double longitude, latitude;
++ double x, y;
++
++ priv = map->priv;
++
++ area.x = 0;
++ area.y = 0;
++ area.width = GTK_WIDGET (map)->allocation.width;
++ area.height = GTK_WIDGET (map)->allocation.height;
++
++ /* Must be done before update_render_pixbuf() */
++
++ e_map_window_to_world (map, area.width / 2, area.height / 2,
++ &longitude, &latitude);
++
++ priv->zoom_state = E_MAP_ZOOMED_OUT;
++ update_render_pixbuf (map, GDK_INTERP_BILINEAR, TRUE);
++
++ e_map_world_to_window (map, longitude, latitude, &x, &y);
++ center_at (map, x + priv->xofs, y + priv->yofs, FALSE);
++/* request_paint_area (map, &area); */
++ repaint_visible (map);
++}
++
++
++static void
++zoom_do (EMap *map)
++{
++ EMapPrivate *priv;
++
++ priv = map->priv;
++
++ gtk_signal_handler_block_by_data (GTK_OBJECT (priv->hadj), map);
++ gtk_signal_handler_block_by_data (GTK_OBJECT (priv->vadj), map);
++
++ if (priv->zoom_state == E_MAP_ZOOMING_IN)
++ {
++ if (e_map_get_smooth_zoom (map)) zoom_in_smooth (map);
++ else zoom_in (map);
++ }
++ else if (priv->zoom_state == E_MAP_ZOOMING_OUT)
++ {
++/* if (e_map_get_smooth_zoom(map)) zoom_out_smooth(map); */
++ zoom_out (map);
++ }
++
++ gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->hadj), map);
++ gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->vadj), map);
++
++ set_scroll_area(map);
++}
++
++
++/* Callback used when an adjustment is changed */
++
++static void
++adjustment_changed_cb (GtkAdjustment *adj, gpointer data)
++{
++ EMap *view;
++ EMapPrivate *priv;
++
++ view = E_MAP (data);
++ priv = view->priv;
++
++ scroll_to (view, priv->hadj->value, priv->vadj->value);
++}
++
++
++static void
++set_scroll_area (EMap *view)
++{
++ EMapPrivate *priv;
++
++ priv = view->priv;
++
++ if (!GTK_WIDGET_REALIZED (GTK_WIDGET (view))) return;
++ if (!priv->hadj || !priv->vadj) return;
++
++ /* Set scroll increments */
++
++ priv->hadj->page_size = GTK_WIDGET (view)->allocation.width;
++ priv->hadj->page_increment = GTK_WIDGET (view)->allocation.width / 2;
++ priv->hadj->step_increment = SCROLL_STEP_SIZE;
++
++ priv->vadj->page_size = GTK_WIDGET (view)->allocation.height;
++ priv->vadj->page_increment = GTK_WIDGET (view)->allocation.height / 2;
++ priv->vadj->step_increment = SCROLL_STEP_SIZE;
++
++ /* Set scroll bounds and new offsets */
++
++ priv->hadj->lower = 0;
++ if (priv->map_render_pixbuf)
++ priv->hadj->upper = gdk_pixbuf_get_width (priv->map_render_pixbuf);
++
++ priv->vadj->lower = 0;
++ if (priv->map_render_pixbuf)
++ priv->vadj->upper = gdk_pixbuf_get_height (priv->map_render_pixbuf);
++
++ gtk_signal_emit_by_name (GTK_OBJECT (priv->hadj), "changed");
++ gtk_signal_emit_by_name (GTK_OBJECT (priv->vadj), "changed");
++
++ priv->xofs = CLAMP (priv->xofs, 0, priv->hadj->upper - priv->hadj->page_size);
++ priv->yofs = CLAMP (priv->yofs, 0, priv->vadj->upper - priv->vadj->page_size);
++
++ if (priv->hadj->value != priv->xofs)
++ {
++ priv->hadj->value = priv->xofs;
++
++ gtk_signal_handler_block_by_data (GTK_OBJECT (priv->hadj), view);
++ gtk_signal_emit_by_name (GTK_OBJECT (priv->hadj), "value_changed");
++ gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->hadj), view);
++ }
++
++ if (priv->vadj->value != priv->yofs)
++ {
++ priv->vadj->value = priv->yofs;
++
++ gtk_signal_handler_block_by_data (GTK_OBJECT (priv->vadj), view);
++ gtk_signal_emit_by_name (GTK_OBJECT (priv->vadj), "value_changed");
++ gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->vadj), view);
++ }
++}
++
+diff -Nrup gnome-panel-2.14.1/applets/clock/e-map/e-map.h ../gnome-panel-2.14.1/applets/clock/e-map/e-map.h
+--- gnome-panel-2.14.1/applets/clock/e-map/e-map.h 1970-01-01 01:00:00.000000000 +0100
++++ ../gnome-panel-2.14.1/applets/clock/e-map/e-map.h 2006-06-12 16:18:42.527305000 +0200
+@@ -0,0 +1,139 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++/* Map widget.
++ *
++ * Copyright (C) 2000-2001 Ximian, Inc.
++ *
++ * Authors: Hans Petter Jansson <[email protected]>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of version 2 of the GNU General Public
++ * License as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public
++ * License along with this program; if not, write to the
++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++ * Boston, MA 02111-1307, USA.
++ */
++
++#ifndef E_MAP_H
++#define E_MAP_H
++
++#include <gtk/gtkwidget.h>
++
++#define TYPE_E_MAP (e_map_get_type ())
++#define E_MAP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_E_MAP, EMap))
++#define E_MAP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_E_MAP, EMapClass))
++#define IS_E_MAP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_E_MAP))
++#define IS_E_MAP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_E_MAP))
++
++typedef struct _EMap EMap;
++typedef struct _EMapClass EMapClass;
++typedef struct _EMapPoint EMapPoint;
++
++struct _EMap
++{
++ GtkWidget widget;
++
++ /* Private data */
++ gpointer priv;
++};
++
++struct _EMapClass
++{
++ GtkWidgetClass parent_class;
++
++ /* Notification signals */
++ void (*zoom_fit) (EMap * view);
++
++ /* GTK+ scrolling interface */
++ void (*set_scroll_adjustments) (GtkWidget * widget,
++ GtkAdjustment * hadj,
++ GtkAdjustment * vadj);
++};
++
++/* The definition of Dot */
++
++struct _EMapPoint
++{
++ gchar *name; /* Can be NULL */
++ double longitude, latitude;
++ guint32 rgba;
++ gpointer user_data;
++};
++
++
++/* --- Widget --- */
++
++GtkType e_map_get_type (void);
++
++EMap *e_map_new (void);
++
++/* Stop doing redraws when map data changes (e.g. by modifying points) */
++void e_map_freeze (EMap *map);
++
++/* Do an immediate repaint, and start doing realtime repaints again */
++void e_map_thaw (EMap *map);
++
++/* --- Coordinate translation --- */
++
++/* Translates window-relative coords to lat/long */
++void e_map_window_to_world (EMap *map,
++ double win_x, double win_y,
++ double *world_longitude, double *world_latitude);
++
++/* Translates lat/long to window-relative coordinates. Note that the
++ * returned coordinates can be negative or greater than the current size
++ * of the allocation area */
++void e_map_world_to_window (EMap *map,
++ double world_longitude, double world_latitude,
++ double *win_x, double *win_y);
++
++/* --- Zoom --- */
++
++double e_map_get_magnification (EMap *map);
++
++/* Pass TRUE if we want the smooth zoom hack */
++void e_map_set_smooth_zoom (EMap *map, gboolean state);
++
++/* TRUE if smooth zoom hack will be employed */
++gboolean e_map_get_smooth_zoom (EMap *map);
++
++/* NB: Function definition will change shortly */
++void e_map_zoom_to_location (EMap *map, double longitude, double latitude);
++
++/* Zoom to mag factor 1.0 */
++void e_map_zoom_out (EMap *map);
++
++/* --- Points --- */
++
++EMapPoint *e_map_add_point (EMap *map, gchar *name,
++ double longitude, double latitude,
++ guint32 color_rgba);
++
++void e_map_remove_point (EMap *map, EMapPoint *point);
++
++void e_map_point_get_location (EMapPoint *point,
++ double *longitude, double *latitude);
++
++gchar *e_map_point_get_name (EMapPoint *point);
++
++guint32 e_map_point_get_color_rgba (EMapPoint *point);
++
++void e_map_point_set_color_rgba (EMap *map, EMapPoint *point, guint32 color_rgba);
++
++void e_map_point_set_data (EMapPoint *point, gpointer data);
++
++gpointer e_map_point_get_data (EMapPoint *point);
++
++gboolean e_map_point_is_in_view (EMap *map, EMapPoint *point);
++
++EMapPoint *e_map_get_closest_point (EMap *map, double longitude, double latitude,
++ gboolean in_view);
++
++#endif
++
+diff -Nrup gnome-panel-2.14.1/applets/clock/multi-timezone.c ../gnome-panel-2.14.1/applets/clock/multi-timezone.c
+--- gnome-panel-2.14.1/applets/clock/multi-timezone.c 1970-01-01 01:00:00.000000000 +0100
++++ ../gnome-panel-2.14.1/applets/clock/multi-timezone.c 2006-06-12 16:18:42.525310000 +0200
+@@ -0,0 +1,541 @@
++#include <strings.h>
++#include "config.h"
++#include "clock.h"
++
++#define GW(name) glade_xml_get_widget (tsd->xml, name)
++static const char* KEY_TIPS_ZONE = "tips-zone";
++/* popup part */
++static void set_tip_zone_to_gconf (TimezoneSelectionDialog *tsd, char *zone, char *nick, int key_num);
++static void update_list_tip_zone (ClockData *cd);
++
++static void
++hide_it (GtkWidget* w, GdkEventButton *event, ClockData *cd)
++{
++ gtk_widget_hide (cd->multizone_popup);
++ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cd->multizone_toggle),
++ FALSE);
++}
++
++static void
++set_zone_tip_from_name (ClockData *cd, GtkWidget *widget, char *zone)
++{
++ TzInfo *tz;
++ TzLocation *tz_loc = NULL;
++
++ if (!zone)
++ return;
++
++ if (!cd->tzdb)
++ {
++ cd->tzdb = tz_load_db ();
++ if (!cd->tzdb)
++ return;
++ }
++
++ tz_loc = tz_get_location_by_name (cd->tzdb, zone);
++
++ if (!tz_loc)
++ {
++ char *current_timezone = tz_get_system_timezone ();
++ if (current_timezone)
++ {
++ tz_loc = tz_get_location_by_name (cd->tzdb,
++ current_timezone);
++ g_free (current_timezone);
++ }
++ }
++ if (tz_loc)
++ {
++ char *tip;
++ tz = tz_info_from_location (tz_loc);
++
++ tip = g_strdup_printf ("%s - %s (%s)\nGMT%s%ld %s%s%s",
++ _(tz_loc->zone),
++ tz_loc->country,
++ tz->tzname_normal,
++ (tz->utc_offset / 3600) >= 0 ? "+" : " ",
++ tz->utc_offset / 3600,
++ tz->daylight == 0 ? " ": _("use daylight savings"),
++ tz_loc->comment ? "\n" : " ",
++ tz_loc->comment ? tz_loc->comment : " ");
++ clock_set_tooltip (cd->applet, widget, tip);
++ g_free (tip);
++ }
++}
++
++static GtkWidget *
++add_timezone_button (ClockData *cd,
++ TipZone *tip)
++{
++ GtkWidget *hbox, *label_zone, *label_time, *event_box;
++
++ hbox = gtk_hbox_new (TRUE, 0);
++ label_zone = gtk_label_new (tip->nick);
++ label_time = gtk_label_new ("12:00");
++ event_box = gtk_event_box_new ();
++
++
++ tip->time_label = label_time;
++ tip->nick_label = label_zone;
++
++
++ gtk_box_pack_start (GTK_BOX (hbox), label_zone, TRUE, TRUE, 2);
++ gtk_misc_set_alignment (GTK_MISC (label_zone), 0, 0.5);
++ gtk_box_pack_start (GTK_BOX (hbox), label_time, TRUE, TRUE, 2);
++ gtk_misc_set_alignment (GTK_MISC (label_time), 1, 0.5);
++
++ gtk_container_add (GTK_CONTAINER (event_box), hbox);
++
++ set_zone_tip_from_name (cd, event_box, tip->zone);
++
++ g_signal_connect (event_box,
++ "button-press-event",
++ G_CALLBACK (hide_it),
++ cd);
++
++ gtk_widget_show_all (event_box);
++ return event_box;
++}
++
++static gboolean
++close_on_escape (GtkWidget *widget,
++ GdkEventKey *event,
++ ClockData *cd)
++{
++ if (event->keyval == GDK_Escape) {
++ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cd->toggle), FALSE);
++ return TRUE;
++ }
++
++ return FALSE;
++}
++
++static gboolean
++delete_event (GtkWidget *widget,
++ GdkEvent *event,
++ ClockData *cd)
++{
++ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cd->toggle), FALSE);
++ return TRUE;
++}
++
++static void
++edit_zones (GtkWidget *w, ClockData *cd)
++{
++ if (cd->multizone_popup)
++ {
++ gtk_widget_hide (cd->multizone_popup);
++ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cd->multizone_toggle),
++ FALSE);
++ }
++ if (cd->tsd)
++ {
++ gtk_window_set_screen (GTK_WINDOW (cd->timezone_dialog),
++ gtk_widget_get_screen (cd->applet));
++ gtk_window_present (GTK_WINDOW (cd->timezone_dialog));
++ return;
++ }
++
++ display_timezone_selection_dialog (NULL, cd, NULL);
++}
++
++GtkWidget *
++create_multi_timezones_popup (ClockData *cd,
++ GdkScreen *screen)
++{
++ GtkWindow *window;
++ GtkWidget *vbox_zones, *vbox, *separ, *button, *frame;
++ GSList *tmp_list;
++
++ update_list_tip_zone (cd);
++
++ window = GTK_WINDOW (gtk_window_new (GTK_WINDOW_POPUP));
++
++ gtk_window_set_type_hint (window, GDK_WINDOW_TYPE_HINT_DOCK);
++ gtk_window_set_decorated (window, FALSE);
++ gtk_window_set_resizable (window, FALSE);
++ gtk_window_stick (window);
++ gtk_window_set_screen (window, screen);
++
++ g_signal_connect (window, "delete_event",
++ G_CALLBACK (delete_event), cd);
++
++ g_signal_connect (window, "key_press_event",
++ G_CALLBACK (close_on_escape), cd);
++
++ vbox_zones = gtk_vbox_new (TRUE, 4);
++ vbox = gtk_vbox_new (FALSE, 4);
++ frame = gtk_frame_new (NULL);
++
++ gtk_container_add (GTK_CONTAINER (frame), vbox);
++
++ for (tmp_list = cd->tip_list;
++ tmp_list ; tmp_list = tmp_list->next)
++ {
++ GtkWidget *zone;
++ TipZone *tip_zone = tmp_list->data;
++
++ zone = add_timezone_button (cd, tip_zone);
++
++ gtk_container_add (GTK_CONTAINER (vbox_zones), zone);
++ }
++
++ gtk_container_add (GTK_CONTAINER (vbox), vbox_zones);
++
++ separ = gtk_hseparator_new ();
++ gtk_container_add (GTK_CONTAINER (vbox), separ);
++
++ button = gtk_button_new_with_label (_("Edit Time Zones..."));
++ gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
++
++ g_signal_connect (button, "clicked", G_CALLBACK (edit_zones),
++ cd);
++
++ gtk_container_add (GTK_CONTAINER (vbox), button);
++
++ gtk_container_add (GTK_CONTAINER (window), frame);
++
++ return GTK_WIDGET (window);
++}
++
++
++static gchar *
++get_timezone_msgid (TimezoneSelectionDialog *tsd, gchar *zone)
++{
++ GPtrArray *locs;
++ gchar *msgid;
++ int i;
++
++ locs = tz_get_locations (tsd->cd->tzdb);
++
++ for (i = 0; i < locs->len; i++)
++ {
++ msgid = tz_location_get_zone (g_ptr_array_index (locs, i));
++
++ if (!g_utf8_collate (_(msgid), zone))
++ {
++ g_free (zone);
++ return g_strdup (msgid);
++ }
++ }
++
++ return zone;
++}
++
++static int
++get_next_available_tips_zone_key_num (TimezoneSelectionDialog *tsd)
++{
++ GSList *list = NULL, *li;
++ int num = -1;
++ char *tips_store_path = panel_applet_gconf_get_full_key (PANEL_APPLET (tsd->cd->applet), KEY_TIPS_ZONE);
++
++
++ list = gconf_client_all_entries (gconf_client_get_default (), tips_store_path, NULL);
++
++ if (list == NULL)
++ return 0;
++
++
++ for (li = list; li != NULL; li = li->next)
++ {
++ GConfEntry *entry = li->data;
++ char *key_name = g_path_get_basename (gconf_entry_get_key (entry));
++ int key_num = atoi (key_name);
++ num = key_num > num ? key_num : num;
++ }
++ return num + 1;
++}
++
++enum {
++ ZONE_COLUMN,
++ NIK_COLUMN,
++ EDITABLE_COL,
++ KEY_NUM_COLUMN,
++ NUM_COLUMNS
++};
++
++void static
++on_add_to_tip_button_clicked (GtkWidget * w,
++ TimezoneSelectionDialog *tsd)
++{
++ GtkTreeIter iter;
++ char *nick;
++ char *zone = g_strdup (gtk_entry_get_text (GTK_ENTRY (GTK_COMBO ( GW ("location_combo"))->entry)));
++ int key_num = get_next_available_tips_zone_key_num (tsd);
++
++ gtk_tree_store_append (tsd->model, &iter, NULL);
++
++ nick = index (zone, '/');
++ if (nick != NULL)
++ nick = strdup (nick + 1);
++ else
++ nick = strdup (zone);
++
++ gtk_tree_store_set (tsd->model, &iter,
++ ZONE_COLUMN, zone,
++ NIK_COLUMN, nick,
++ EDITABLE_COL, TRUE,
++ KEY_NUM_COLUMN, key_num,
++ -1);
++
++ zone = get_timezone_msgid (tsd, zone);
++
++ set_tip_zone_to_gconf (tsd, zone, nick, key_num);
++
++ gtk_widget_set_sensitive (GW ("remove_from_tip_button"), TRUE);
++ gtk_widget_set_sensitive (GW ("add_to_tip_button"), FALSE);
++
++ g_free (zone);
++ update_list_tip_zone (tsd->cd);
++}
++
++void static
++on_remove_from_tip_button_clicked (GtkWidget *widget,
++ TimezoneSelectionDialog *tsd)
++{
++ GtkTreeIter iter;
++ GtkTreeModel *model;
++ gchar *zone, *nick;
++ GtkTreeSelection *sel;
++
++ sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (tsd->tips_tree));
++
++ if (gtk_tree_selection_get_selected (sel, &model, &iter))
++ {
++ char *path, *key;
++ int key_num;
++
++ gtk_tree_model_get (model, &iter,
++ ZONE_COLUMN, &zone,
++ NIK_COLUMN, &nick,
++ KEY_NUM_COLUMN, &key_num,
++ -1);
++
++ gtk_tree_store_remove (GTK_TREE_STORE (model), &iter);
++
++ path = panel_applet_gconf_get_full_key (PANEL_APPLET (tsd->cd->applet),
++ KEY_TIPS_ZONE);
++ key = g_strdup_printf ("%s/%d", path, key_num);
++
++ gconf_client_unset (gconf_client_get_default (), key, NULL);
++
++ g_free (zone);
++ g_free (nick);
++ update_list_tip_zone (tsd->cd);
++ }
++}
++
++static void set_tip_zone_to_gconf (TimezoneSelectionDialog *tsd,
++ char *zone,
++ char *nick,
++ int key_num)
++{
++ char *path = panel_applet_gconf_get_full_key (PANEL_APPLET (tsd->cd->applet),
++ KEY_TIPS_ZONE);
++
++ char *key_name = g_strdup_printf ("%s/%d", path, key_num);
++
++ gconf_client_set_pair (gconf_client_get_default (),
++ key_name,
++ GCONF_VALUE_STRING,
++ GCONF_VALUE_STRING,
++ &zone,
++ &nick,
++ NULL);
++ g_free (path);
++ g_free (key_name);
++}
++
++static void
++edited (GtkCellRendererText *cell,
++ gchar *path_string,
++ gchar *new_text,
++ TimezoneSelectionDialog *tsd)
++{
++ GtkTreeModel *model = GTK_TREE_MODEL (tsd->model);
++ GtkTreeIter iter;
++ GtkTreePath *path = gtk_tree_path_new_from_string (path_string);
++ char *zone;
++ int key_num;
++
++ gtk_tree_model_get_iter (model, &iter, path);
++
++ gtk_tree_model_get (model, &iter, ZONE_COLUMN, &zone, KEY_NUM_COLUMN, &key_num, -1);
++
++ zone = get_timezone_msgid (tsd, zone);
++
++ gtk_tree_store_set (GTK_TREE_STORE (model), &iter, NIK_COLUMN, new_text, -1);
++
++ set_tip_zone_to_gconf (tsd, zone, new_text, key_num);
++
++ gtk_tree_path_free (path);
++ g_free (zone);
++ update_list_tip_zone (tsd->cd);
++}
++static void
++populate_tips_store (TimezoneSelectionDialog *tsd, GtkTreeStore *model)
++{
++ char *tips_store_path;
++ GConfClient *client;
++ GSList *list = NULL, *li;
++ GtkTreeIter iter;
++ client = gconf_client_get_default ();
++
++ tips_store_path = panel_applet_gconf_get_full_key (PANEL_APPLET (tsd->cd->applet),
++ KEY_TIPS_ZONE);
++
++ list = gconf_client_all_entries (client, tips_store_path, NULL);
++
++ if (!list)
++ gtk_widget_set_sensitive (GW ("remove_from_tip_button"), FALSE);
++
++ for (li = list; li != NULL; li = li->next)
++ {
++ char *zone, *nick;
++ GConfEntry *entry = li->data;
++ char *key_name = g_path_get_basename (gconf_entry_get_key (entry));
++ GConfValue *key_value = gconf_entry_get_value (entry);
++ int key_num = atoi (key_name);
++
++ zone = g_strdup (gconf_value_get_string (gconf_value_get_car (key_value)));
++ nick = g_strdup (gconf_value_get_string (gconf_value_get_cdr (key_value)));
++
++ gtk_tree_store_append (model, &iter, NULL);
++
++ gtk_tree_store_set (model, &iter,
++ ZONE_COLUMN, _(zone),
++ NIK_COLUMN, nick,
++ EDITABLE_COL, TRUE,
++ KEY_NUM_COLUMN, key_num,
++ -1);
++
++ g_free (key_name);
++ g_free (zone);
++ g_free (nick);
++ }
++
++ g_free (tips_store_path);
++}
++
++void
++create_multizone_table (TimezoneSelectionDialog *tsd)
++{
++ GtkTreeStore *model;
++ GtkWidget *tree_view;
++ GtkCellRenderer *renderer;
++
++ model = gtk_tree_store_new (NUM_COLUMNS,
++ G_TYPE_STRING,
++ G_TYPE_STRING,
++ G_TYPE_BOOLEAN,
++ G_TYPE_INT);
++
++
++ populate_tips_store (tsd, model);
++
++ tsd->tips_tree = GW ("tips_tree");
++ tree_view = tsd->tips_tree;
++ tsd->model = model;
++
++ gtk_tree_view_set_model (GTK_TREE_VIEW (tree_view), GTK_TREE_MODEL (model));
++ gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (tree_view), TRUE);
++
++ renderer = gtk_cell_renderer_text_new ();
++ gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree_view),
++ -1, _("Time zone"),
++ renderer,
++ "text", ZONE_COLUMN,
++ NULL);
++ g_signal_connect (renderer, "edited",
++ G_CALLBACK (edited), model);
++
++ renderer = gtk_cell_renderer_text_new ();
++
++ gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree_view),
++ -1, _("Comments"),
++ renderer,
++ "text", NIK_COLUMN,
++ "editable", EDITABLE_COL,
++ NULL);
++ g_signal_connect (renderer, "edited",
++ G_CALLBACK (edited), tsd);
++
++ gtk_widget_show (tree_view);
++
++ g_signal_connect (G_OBJECT (GW ("add_to_tip_button")), "clicked",
++ G_CALLBACK (on_add_to_tip_button_clicked), tsd);
++
++ g_signal_connect (G_OBJECT (GW ("remove_from_tip_button")), "clicked",
++ G_CALLBACK (on_remove_from_tip_button_clicked), tsd);
++
++
++}
++
++static void free_tip_list (GSList *tips)
++{
++ if (tips)
++ {
++ GSList *tmp_list;
++ for (tmp_list = tips; tmp_list ; tmp_list = tmp_list->next)
++ {
++ TipZone *tip_tmp = tmp_list->data;
++ g_free (tip_tmp->zone);
++ g_free (tip_tmp->nick);
++ g_free (tip_tmp);
++ }
++ g_slist_free (tips);
++ }
++}
++
++static void
++update_list_tip_zone (ClockData *cd)
++{
++ GSList *list = NULL, *li;
++
++ char *tips_store_path = panel_applet_gconf_get_full_key (PANEL_APPLET (cd->applet), KEY_TIPS_ZONE);
++
++ free_tip_list (cd->tip_list);
++ cd->tip_list = NULL;
++
++ if (cd->multizone_popup)
++ {
++ gtk_widget_destroy (cd->multizone_popup);
++ cd->multizone_popup = NULL;
++ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cd->multizone_toggle),
++ FALSE);
++ }
++
++ list = gconf_client_all_entries (gconf_client_get_default (),
++ tips_store_path, NULL);
++
++ if (list == NULL)
++ return;
++
++ for (li = list; li != NULL; li = li->next)
++ {
++ GConfEntry *entry = li->data;
++ GConfValue *key_value = gconf_entry_get_value (entry);
++ if (key_value)
++ {
++ TipZone *tip_zone = g_new (TipZone, 1);
++ tip_zone->zone = g_strdup (gconf_value_get_string (gconf_value_get_car (key_value)));
++ tip_zone->nick = g_strdup (gconf_value_get_string (gconf_value_get_cdr (key_value)));
++ cd->tip_list = g_slist_append (cd->tip_list, tip_zone);
++ }
++ }
++}
++
++gboolean
++multizone_is_zone_in_tip_list (ClockData *cd, char *zone)
++{
++ GSList *tmp_list = NULL;
++ for (tmp_list = cd->tip_list; tmp_list ; tmp_list = tmp_list->next)
++ {
++ TipZone *tip_tmp = tmp_list->data;
++ if (strcmp (tip_tmp->zone, zone) == 0)
++ return TRUE;
++ }
++ return FALSE;
++}
++
++
+diff -Nrup gnome-panel-2.14.1/applets/clock/timezone-selection.c ../gnome-panel-2.14.1/applets/clock/timezone-selection.c
+--- gnome-panel-2.14.1/applets/clock/timezone-selection.c 1970-01-01 01:00:00.000000000 +0100
++++ ../gnome-panel-2.14.1/applets/clock/timezone-selection.c 2006-06-12 16:18:42.524394000 +0200
+@@ -0,0 +1,451 @@
++#include "config.h"
++#include "clock.h"
++
++
++#define GW(name) glade_xml_get_widget (tsd->xml, name)
++
++static void
++mark_selected_city (TimezoneSelectionDialog * tsd, gchar * defaultv);
++
++static void
++display_help (GtkWidget * w, gpointer data)
++{
++ GError *error = NULL;
++
++ gnome_help_display_desktop_on_screen (NULL, "clock", "clock", "clock-usage",
++ gtk_widget_get_screen (w), &error);
++
++ if (error)
++ {
++ GtkWidget *dialog;
++ dialog = gtk_message_dialog_new (GTK_WINDOW (w),
++ GTK_DIALOG_DESTROY_WITH_PARENT,
++ GTK_MESSAGE_ERROR,
++ GTK_BUTTONS_OK,
++ _("There was an error displaying help: %s"),
++ error->message);
++
++ g_signal_connect (G_OBJECT (dialog), "response",
++ G_CALLBACK (gtk_widget_destroy), NULL);
++
++ gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
++ gtk_window_set_screen (GTK_WINDOW (dialog), gtk_widget_get_screen (w));
++ gtk_widget_show (dialog);
++ g_error_free (error);
++ }
++}
++
++
++static TzLocation *
++tz_location_from_point (TimezoneSelectionDialog * tsd, EMapPoint * point)
++{
++ TzLocation *tz_loc = NULL;
++ GPtrArray *locs;
++ double p_longitude, p_latitude;
++ double l_longitude, l_latitude;
++ int i;
++
++ locs = tz_get_locations (tsd->cd->tzdb);
++ e_map_point_get_location (point, &p_longitude, &p_latitude);
++
++ for (i = 0; i < locs->len; i++)
++ {
++ tz_location_get_position (g_ptr_array_index (locs, i),
++ &l_longitude, &l_latitude);
++
++ if (l_longitude - 0.005 <= p_longitude &&
++ l_longitude + 0.005 >= p_longitude &&
++ l_latitude - 0.005 <= p_latitude &&
++ l_latitude + 0.005 >= p_latitude)
++ {
++ tz_loc = g_ptr_array_index (locs, i);
++ break;
++ }
++ }
++
++ return (tz_loc);
++}
++
++static void
++set_tz_from_name (TimezoneSelectionDialog * tsd, gchar * name)
++{
++ TzLocation *tz_loc = NULL;
++ GPtrArray *locs;
++ double l_longitude = 0.0, l_latitude = 0.0;
++ int i;
++
++ locs = tz_get_locations (tsd->cd->tzdb);
++
++ for (i = 0; i < locs->len; i++)
++ {
++ tz_loc = g_ptr_array_index (locs, i);
++
++ if (tz_loc
++ && (!g_utf8_collate (_(tz_location_get_zone (tz_loc)), _(name))))
++ {
++ tz_location_get_position (tz_loc, &l_longitude, &l_latitude);
++ break;
++ }
++ }
++
++ if (tsd->point_selected)
++ e_map_point_set_color_rgba (tsd->map,
++ tsd->point_selected,
++ TZ_MAP_POINT_NORMAL_RGBA);
++ tsd->point_selected =
++ e_map_get_closest_point (tsd->map, l_longitude, l_latitude, FALSE);
++
++ gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (GW ("location_combo"))->entry),
++ _(tz_location_get_zone
++ (tz_location_from_point (tsd, tsd->point_selected))));
++}
++
++static gchar *
++get_selected_tz_name (TimezoneSelectionDialog * tsd)
++{
++ gchar *entry_text;
++
++ entry_text =
++ (gchar *)
++ gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (GW ("location_combo"))->entry));
++
++ return entry_text;
++}
++
++static gboolean
++update_map (GtkWidget * w, gpointer data)
++{
++ TimezoneSelectionDialog *tsd = (TimezoneSelectionDialog *) data;
++ char *timezone = (char *) gtk_entry_get_text (GTK_ENTRY (w));
++
++ if (strlen (timezone) > 0)
++ {
++ gchar *tz_name;
++ TzLocation *tz_location;
++
++ set_tz_from_name (tsd, g_strdup (timezone));
++
++ tz_name = get_selected_tz_name (tsd);
++ tz_location = tz_get_location_by_name (tsd->cd->tzdb, tz_name);
++ }
++
++ gtk_widget_set_sensitive (GW ("add_to_tip_button"),
++ !multizone_is_zone_in_tip_list(tsd->cd, timezone));
++
++ return TRUE;
++}
++
++static gboolean
++out_map (GtkWidget * w, GdkEventCrossing * event, gpointer data)
++{
++ const char *old_zone;
++ TimezoneSelectionDialog *tsd = (TimezoneSelectionDialog *) data;
++ GtkWidget *location_label = GW ("location_label");
++
++ if (event->mode != GDK_CROSSING_NORMAL)
++ return FALSE;
++
++ if (tsd->point_hover && tsd->point_hover != tsd->point_selected)
++ e_map_point_set_color_rgba (tsd->map, tsd->point_hover,
++ TZ_MAP_POINT_NORMAL_RGBA);
++
++ tsd->point_hover = NULL;
++
++ old_zone = gtk_label_get_text (GTK_LABEL (location_label));
++
++ if (strcmp (old_zone, ""))
++ {
++ gtk_label_set_text (GTK_LABEL (location_label), "");
++ gtk_label_set_text (GTK_LABEL (GW ("time_clock_label")), "");
++ }
++
++ return TRUE;
++}
++
++static gboolean
++button_pressed (GtkWidget * w, GdkEventButton * event, gpointer data)
++{
++ double longitude, latitude;
++ TimezoneSelectionDialog *tsd = (TimezoneSelectionDialog *) data;
++ GtkWidget *zoom_label = GW ("zoom_label");
++
++ e_map_window_to_world (tsd->map, (double) event->x, (double) event->y,
++ &longitude, &latitude);
++
++ if (event->button != 1)
++ {
++ e_map_zoom_out (tsd->map);
++ gtk_label_set_text (GTK_LABEL (zoom_label),
++ _("Click on your nearest city or select it from the list (left click to zoom in):"));
++ }
++ else
++ {
++ GtkWidget *location_entry;
++ TzLocation *tz_location;
++ gchar *entry_text, *entry_text_new;
++
++ if (e_map_get_magnification (tsd->map) <= 1.0)
++ e_map_zoom_to_location (tsd->map, longitude, latitude);
++
++ if (tsd->point_selected)
++ e_map_point_set_color_rgba (tsd->map,
++ tsd->point_selected,
++ TZ_MAP_POINT_NORMAL_RGBA);
++ tsd->point_selected = tsd->point_hover;
++
++ location_entry = GTK_COMBO (GW ("location_combo"))->entry;
++ tz_location = tz_location_from_point (tsd, tsd->point_selected);
++
++ entry_text = (gchar *) gtk_entry_get_text (GTK_ENTRY (location_entry));
++ entry_text_new = _(tz_location_get_zone (tz_location));
++
++
++ if (!entry_text || !entry_text_new
++ || g_utf8_collate (entry_text, entry_text_new))
++ {
++ gtk_entry_set_text (GTK_ENTRY (location_entry), entry_text_new);
++ gtk_widget_set_sensitive (GW ("add_to_tip_button"),
++ !multizone_is_zone_in_tip_list(tsd->cd, entry_text_new));
++ }
++ gtk_label_set_text (GTK_LABEL (zoom_label),
++ _("Click on your nearest city or select it from the list (right click to zoom out):"));
++ mark_selected_city (tsd, entry_text_new);
++ }
++
++ return TRUE;
++}
++
++static gboolean
++motion (GtkWidget * widget, GdkEventMotion * event, gpointer data)
++{
++ TimezoneSelectionDialog *tsd = (TimezoneSelectionDialog *) data;
++ double longitude, latitude;
++ GtkWidget *time_label = GW ("time_clock_label");
++ GtkWidget *location_label = GW ("location_label");
++
++
++ e_map_window_to_world (tsd->map, (double) event->x, (double) event->y,
++ &longitude, &latitude);
++
++ if (tsd->point_hover && tsd->point_hover != tsd->point_selected)
++ e_map_point_set_color_rgba (tsd->map, tsd->point_hover,
++ TZ_MAP_POINT_NORMAL_RGBA);
++
++ tsd->point_hover =
++ e_map_get_closest_point (tsd->map, longitude, latitude, TRUE);
++
++ if (tsd->point_hover != tsd->point_selected)
++ e_map_point_set_color_rgba (tsd->map, tsd->point_hover,
++ TZ_MAP_POINT_HOVER_RGBA);
++
++ tsd->correction =
++ tz_location_get_utc_offset (tz_location_from_point
++ (tsd, tsd->point_hover));
++
++ /* e_tz_map_location_from_point() can in theory return NULL, but in
++ * practice there are no reasons why it should */
++
++ gtk_label_set_text (GTK_LABEL (location_label),
++ _(tz_location_get_zone
++ (tz_location_from_point (tsd, tsd->point_hover))));
++
++ if (strcmp (gtk_label_get_text (GTK_LABEL (location_label)), "") == 0)
++ {
++ gtk_label_set_text (GTK_LABEL (time_label), "");
++ }
++ else
++ {
++ struct tm tm;
++ time_t tt;
++ char clock[256];
++
++ time (&tt);
++ tt += tsd->correction;
++ gmtime_r (&tt, &tm);
++ memset (clock, 0, 256);
++ sprintf (clock, "%02d:%02d:%02d", tm.tm_hour, tm.tm_min, tm.tm_sec);
++ gtk_label_set_text (GTK_LABEL (time_label), clock);
++ }
++
++
++ return TRUE;
++}
++
++static gboolean
++flash_selected_point (gpointer data)
++{
++ TimezoneSelectionDialog *tsd = (TimezoneSelectionDialog *) data;
++
++ if (!IS_E_MAP (tsd->map))
++ return FALSE;
++
++ if (!tsd->point_selected)
++ return TRUE;
++
++ if (e_map_point_get_color_rgba (tsd->point_selected) ==
++ TZ_MAP_POINT_SELECTED_1_RGBA)
++ e_map_point_set_color_rgba (tsd->map, tsd->point_selected,
++ TZ_MAP_POINT_SELECTED_2_RGBA);
++ else
++ e_map_point_set_color_rgba (tsd->map, tsd->point_selected,
++ TZ_MAP_POINT_SELECTED_1_RGBA);
++
++ return TRUE;
++}
++
++
++static void
++mark_selected_city (TimezoneSelectionDialog * tsd, gchar * defaultv)
++{
++ TzLocation *tz_loc = NULL;
++ GPtrArray *locs;
++ int i;
++ double l_longitude = 0.0, l_latitude = 0.0;
++ char *system_timezone = tz_get_system_timezone ();
++
++ if (!defaultv || !strcmp ("localtimezone", defaultv))
++ tsd->zone = g_strdup (system_timezone);
++ else
++ {
++ g_free (tsd->zone);
++ tsd->zone = g_strdup (defaultv);
++ }
++
++ locs = tz_get_locations (tsd->cd->tzdb);
++
++ for (i = 0; i < locs->len; i++)
++ {
++ tz_loc = g_ptr_array_index (locs, i);
++
++ if (tz_loc
++ &&
++ (!g_utf8_collate (_(tz_location_get_zone (tz_loc)), _(tsd->zone))))
++ {
++ tz_location_get_position (tz_loc, &l_longitude, &l_latitude);
++ break;
++ }
++ }
++
++ if (tsd->point_selected)
++ e_map_point_set_color_rgba (tsd->map,
++ tsd->point_selected,
++ TZ_MAP_POINT_NORMAL_RGBA);
++ tsd->point_selected =
++ e_map_get_closest_point (tsd->map, l_longitude, l_latitude, FALSE);
++
++ gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (GW ("location_combo"))->entry),
++ _(tz_location_get_zone (tz_location_from_point
++ (tsd, tsd->point_selected))));
++}
++
++static void
++reset_zone (GtkWidget * w, TimezoneSelectionDialog * tsd)
++{
++ char *current_zone = tz_get_system_timezone ();
++
++ mark_selected_city (tsd, current_zone);
++
++ g_free (current_zone);
++}
++
++void
++display_timezone_selection_dialog (BonoboUIComponent *uic,
++ ClockData *cd,
++ const gchar *verbname)
++{
++ GtkWidget *location_entry;
++ GPtrArray *locs;
++ GList *items = NULL;
++ int i;
++ TimezoneSelectionDialog *tsd;
++
++ if (cd->timezone_dialog)
++ {
++ gtk_window_set_screen (GTK_WINDOW (cd->timezone_dialog),
++ gtk_widget_get_screen (cd->applet));
++ gtk_window_present (GTK_WINDOW (cd->timezone_dialog));
++ e_map_zoom_out (cd->tsd->map);
++ return;
++ }
++
++ tsd = g_new0 (TimezoneSelectionDialog, 1);
++
++ tsd->cd = cd;
++ cd->tsd = tsd;
++
++ tsd->xml = glade_xml_new (GLADEDIR "/timezone.glade", NULL, NULL);
++
++ if (tsd->xml == NULL)
++ {
++ g_warning (G_STRLOC "timezone.glade cannot be found");
++ return;
++ }
++ glade_xml_signal_autoconnect (tsd->xml);
++
++ tsd->map = e_map_new ();
++
++ e_map_set_smooth_zoom (tsd->map, TRUE);
++
++ gtk_widget_set_events (GTK_WIDGET (tsd->map),
++ gtk_widget_get_events (GTK_WIDGET (tsd->map)) |
++ GDK_LEAVE_NOTIFY_MASK | GDK_VISIBILITY_NOTIFY_MASK);
++
++ gtk_container_add (GTK_CONTAINER (GW ("map_window")),
++ GTK_WIDGET (tsd->map));
++ gtk_widget_show (GTK_WIDGET (tsd->map));
++
++
++ if (!cd->tzdb)
++ cd->tzdb = tz_load_db ();
++ if (!cd->tzdb)
++ {
++ g_warning (G_STRLOC "Unable to load system timezone database.");
++ return;
++ }
++
++ locs = tz_get_locations (cd->tzdb);
++
++ for (i = 0; g_ptr_array_index (locs, i); i++)
++ {
++ TzLocation *tzl;
++ tzl = g_ptr_array_index (locs, i);
++ e_map_add_point (tsd->map, NULL, tzl->longitude, tzl->latitude,
++ TZ_MAP_POINT_NORMAL_RGBA);
++ items = g_list_append (items, _(tzl->zone));
++ }
++
++ gtk_combo_set_popdown_strings (GTK_COMBO (GW ("location_combo")), items);
++
++ mark_selected_city (tsd, "localtimezone");
++
++ tsd->timeout = g_timeout_add (100, flash_selected_point, (gpointer) tsd);
++
++ g_signal_connect (G_OBJECT (tsd->map), "motion-notify-event",
++ G_CALLBACK (motion), (gpointer) tsd);
++ g_signal_connect (G_OBJECT (tsd->map), "button-press-event",
++ G_CALLBACK (button_pressed), (gpointer) tsd);
++ g_signal_connect (G_OBJECT (tsd->map), "leave-notify-event",
++ G_CALLBACK (out_map), (gpointer) tsd);
++
++ location_entry = GTK_COMBO (GW ("location_combo"))->entry;
++ g_signal_connect (G_OBJECT (location_entry), "changed",
++ G_CALLBACK (update_map), (gpointer) tsd);
++
++ g_signal_connect (G_OBJECT (GW ("reset_button")), "clicked",
++ G_CALLBACK (reset_zone), tsd);
++
++ g_signal_connect (G_OBJECT (GW ("helpbutton")), "clicked",
++ G_CALLBACK (display_help), tsd);
++
++ tsd->dialog = GW ("timezone_dialog");
++ cd->timezone_dialog = tsd->dialog;
++
++ gtk_window_set_screen (GTK_WINDOW (cd->timezone_dialog),
++ gtk_widget_get_screen (cd->applet));
++
++ create_multizone_table (tsd);
++
++ gtk_widget_show_all (cd->timezone_dialog);
++
++}
++
+diff -Nrup gnome-panel-2.14.1/applets/clock/timezone.glade ../gnome-panel-2.14.1/applets/clock/timezone.glade
+--- gnome-panel-2.14.1/applets/clock/timezone.glade 1970-01-01 01:00:00.000000000 +0100
++++ ../gnome-panel-2.14.1/applets/clock/timezone.glade 2006-06-12 16:18:42.525014000 +0200
+@@ -0,0 +1,622 @@
++<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
++<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
++
++<glade-interface>
++<requires lib="gnome"/>
++
++<widget class="GtkDialog" id="timezone_dialog">
++ <property name="width_request">545</property>
++ <property name="height_request">575</property>
++ <property name="title" translatable="yes">Change Clock Applet Time Zone</property>
++ <property name="type">GTK_WINDOW_TOPLEVEL</property>
++ <property name="window_position">GTK_WIN_POS_NONE</property>
++ <property name="modal">False</property>
++ <property name="resizable">True</property>
++ <property name="destroy_with_parent">False</property>
++ <property name="decorated">True</property>
++ <property name="skip_taskbar_hint">False</property>
++ <property name="skip_pager_hint">False</property>
++ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
++ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
++ <property name="focus_on_map">True</property>
++ <property name="urgency_hint">False</property>
++ <property name="has_separator">True</property>
++ <signal name="delete_event" handler="gtk_widget_hide" last_modification_time="Thu, 20 Nov 2003 16:52:00 GMT"/>
++ <signal name="destroy_event" handler="gtk_widget_hide" last_modification_time="Thu, 20 Nov 2003 16:52:19 GMT"/>
++
++ <child internal-child="vbox">
++ <widget class="GtkVBox" id="dialog-vbox3">
++ <property name="width_request">635</property>
++ <property name="height_request">384</property>
++ <property name="visible">True</property>
++ <property name="homogeneous">False</property>
++ <property name="spacing">0</property>
++
++ <child internal-child="action_area">
++ <widget class="GtkHButtonBox" id="dialog-action_area3">
++ <property name="visible">True</property>
++ <property name="layout_style">GTK_BUTTONBOX_END</property>
++
++ <child>
++ <widget class="GtkButton" id="helpbutton">
++ <property name="visible">True</property>
++ <property name="can_default">True</property>
++ <property name="can_focus">True</property>
++ <property name="label">gtk-help</property>
++ <property name="use_stock">True</property>
++ <property name="relief">GTK_RELIEF_NORMAL</property>
++ <property name="focus_on_click">True</property>
++ <property name="response_id">-11</property>
++ </widget>
++ </child>
++
++ <child>
++ <widget class="GtkButton" id="timezone_apply_button">
++ <property name="visible">True</property>
++ <property name="can_default">True</property>
++ <property name="can_focus">True</property>
++ <property name="label">gtk-close</property>
++ <property name="use_stock">True</property>
++ <property name="relief">GTK_RELIEF_NORMAL</property>
++ <property name="focus_on_click">True</property>
++ <property name="response_id">-7</property>
++ <signal name="clicked" handler="gtk_widget_hide" object="timezone_dialog" last_modification_time="Thu, 20 Nov 2003 17:54:21 GMT"/>
++ </widget>
++ </child>
++ </widget>
++ <packing>
++ <property name="padding">0</property>
++ <property name="expand">False</property>
++ <property name="fill">False</property>
++ <property name="pack_type">GTK_PACK_END</property>
++ </packing>
++ </child>
++
++ <child>
++ <widget class="GtkVBox" id="time_zone_dialog_content">
++ <property name="border_width">12</property>
++ <property name="visible">True</property>
++ <property name="homogeneous">False</property>
++ <property name="spacing">12</property>
++
++ <child>
++ <widget class="GtkLabel" id="zoom_label">
++ <property name="visible">True</property>
++ <property name="label" translatable="yes">Click on your nearest city or select it from the list (left click to zoom in):</property>
++ <property name="use_underline">False</property>
++ <property name="use_markup">True</property>
++ <property name="justify">GTK_JUSTIFY_LEFT</property>
++ <property name="wrap">False</property>
++ <property name="selectable">False</property>
++ <property name="xalign">0</property>
++ <property name="yalign">0.5</property>
++ <property name="xpad">0</property>
++ <property name="ypad">0</property>
++ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
++ <property name="width_chars">-1</property>
++ <property name="single_line_mode">False</property>
++ <property name="angle">0</property>
++ </widget>
++ <packing>
++ <property name="padding">0</property>
++ <property name="expand">False</property>
++ <property name="fill">False</property>
++ </packing>
++ </child>
++
++ <child>
++ <widget class="GtkVBox" id="timezone_vbox">
++ <property name="width_request">335</property>
++ <property name="height_request">337</property>
++ <property name="visible">True</property>
++ <property name="homogeneous">False</property>
++ <property name="spacing">12</property>
++
++ <child>
++ <widget class="GtkScrolledWindow" id="map_window">
++ <property name="width_request">60</property>
++ <property name="height_request">230</property>
++ <property name="visible">True</property>
++ <property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property>
++ <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
++ <property name="shadow_type">GTK_SHADOW_IN</property>
++ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
++
++ <child>
++ <placeholder/>
++ </child>
++ </widget>
++ <packing>
++ <property name="padding">0</property>
++ <property name="expand">True</property>
++ <property name="fill">True</property>
++ </packing>
++ </child>
++
++ <child>
++ <widget class="GtkHBox" id="hbox52">
++ <property name="visible">True</property>
++ <property name="homogeneous">True</property>
++ <property name="spacing">0</property>
++
++ <child>
++ <widget class="GtkLabel" id="location_label">
++ <property name="visible">True</property>
++ <property name="label" translatable="yes"></property>
++ <property name="use_underline">False</property>
++ <property name="use_markup">False</property>
++ <property name="justify">GTK_JUSTIFY_LEFT</property>
++ <property name="wrap">False</property>
++ <property name="selectable">False</property>
++ <property name="xalign">0</property>
++ <property name="yalign">0.5</property>
++ <property name="xpad">0</property>
++ <property name="ypad">11</property>
++ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
++ <property name="width_chars">-1</property>
++ <property name="single_line_mode">False</property>
++ <property name="angle">0</property>
++ </widget>
++ <packing>
++ <property name="padding">0</property>
++ <property name="expand">False</property>
++ <property name="fill">False</property>
++ </packing>
++ </child>
++
++ <child>
++ <widget class="GtkLabel" id="time_clock_label">
++ <property name="visible">True</property>
++ <property name="label" translatable="yes"></property>
++ <property name="use_underline">False</property>
++ <property name="use_markup">False</property>
++ <property name="justify">GTK_JUSTIFY_RIGHT</property>
++ <property name="wrap">False</property>
++ <property name="selectable">False</property>
++ <property name="xalign">1</property>
++ <property name="yalign">0.5</property>
++ <property name="xpad">0</property>
++ <property name="ypad">0</property>
++ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
++ <property name="width_chars">-1</property>
++ <property name="single_line_mode">False</property>
++ <property name="angle">0</property>
++ </widget>
++ <packing>
++ <property name="padding">0</property>
++ <property name="expand">False</property>
++ <property name="fill">False</property>
++ </packing>
++ </child>
++ </widget>
++ <packing>
++ <property name="padding">0</property>
++ <property name="expand">False</property>
++ <property name="fill">False</property>
++ </packing>
++ </child>
++
++ <child>
++ <widget class="GtkHBox" id="hbox_main_zone">
++ <property name="visible">True</property>
++ <property name="homogeneous">False</property>
++ <property name="spacing">19</property>
++
++ <child>
++ <widget class="GtkLabel" id="label45">
++ <property name="visible">True</property>
++ <property name="label" translatable="yes">Time _zone:</property>
++ <property name="use_underline">True</property>
++ <property name="use_markup">False</property>
++ <property name="justify">GTK_JUSTIFY_CENTER</property>
++ <property name="wrap">False</property>
++ <property name="selectable">False</property>
++ <property name="xalign">0.5</property>
++ <property name="yalign">0.5</property>
++ <property name="xpad">0</property>
++ <property name="ypad">0</property>
++ <property name="mnemonic_widget">entry_location</property>
++ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
++ <property name="width_chars">-1</property>
++ <property name="single_line_mode">False</property>
++ <property name="angle">0</property>
++ </widget>
++ <packing>
++ <property name="padding">0</property>
++ <property name="expand">False</property>
++ <property name="fill">False</property>
++ </packing>
++ </child>
++
++ <child>
++ <widget class="GtkCombo" id="location_combo">
++ <property name="visible">True</property>
++ <property name="value_in_list">False</property>
++ <property name="allow_empty">False</property>
++ <property name="case_sensitive">False</property>
++ <property name="enable_arrow_keys">True</property>
++ <property name="enable_arrows_always">True</property>
++
++ <child internal-child="entry">
++ <widget class="GtkEntry" id="entry_location">
++ <property name="visible">True</property>
++ <property name="editable">False</property>
++ <property name="visibility">True</property>
++ <property name="max_length">0</property>
++ <property name="text" translatable="yes"></property>
++ <property name="has_frame">True</property>
++ <property name="invisible_char">*</property>
++ <property name="activates_default">False</property>
++ </widget>
++ </child>
++
++ <child internal-child="list">
++ <widget class="GtkList" id="convertwidget5">
++ <property name="visible">True</property>
++ <property name="selection_mode">GTK_SELECTION_BROWSE</property>
++
++ <child>
++ <widget class="GtkListItem" id="convertwidget6">
++ <property name="visible">True</property>
++
++ <child>
++ <widget class="GtkLabel" id="convertwidget7">
++ <property name="visible">True</property>
++ <property name="label" translatable="yes"></property>
++ <property name="use_underline">False</property>
++ <property name="use_markup">False</property>
++ <property name="justify">GTK_JUSTIFY_LEFT</property>
++ <property name="wrap">False</property>
++ <property name="selectable">False</property>
++ <property name="xalign">0</property>
++ <property name="yalign">0.5</property>
++ <property name="xpad">0</property>
++ <property name="ypad">0</property>
++ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
++ <property name="width_chars">-1</property>
++ <property name="single_line_mode">False</property>
++ <property name="angle">0</property>
++ </widget>
++ </child>
++ </widget>
++ </child>
++ </widget>
++ </child>
++ </widget>
++ <packing>
++ <property name="padding">0</property>
++ <property name="expand">True</property>
++ <property name="fill">True</property>
++ </packing>
++ </child>
++
++ <child>
++ <placeholder/>
++ </child>
++ </widget>
++ <packing>
++ <property name="padding">0</property>
++ <property name="expand">False</property>
++ <property name="fill">False</property>
++ </packing>
++ </child>
++ </widget>
++ <packing>
++ <property name="padding">0</property>
++ <property name="expand">True</property>
++ <property name="fill">True</property>
++ </packing>
++ </child>
++
++ <child>
++ <widget class="GtkHSeparator" id="hseparator_main_zone">
++ <property name="visible">True</property>
++ </widget>
++ <packing>
++ <property name="padding">0</property>
++ <property name="expand">True</property>
++ <property name="fill">True</property>
++ </packing>
++ </child>
++
++ <child>
++ <widget class="GtkHBox" id="tip_options_vbox">
++ <property name="homogeneous">False</property>
++ <property name="spacing">6</property>
++
++ <child>
++ <widget class="GtkVBox" id="vbox27">
++ <property name="visible">True</property>
++ <property name="homogeneous">False</property>
++ <property name="spacing">0</property>
++
++ <child>
++ <widget class="GtkLabel" id="label127">
++ <property name="visible">True</property>
++ <property name="label" translatable="yes">_List:</property>
++ <property name="use_underline">True</property>
++ <property name="use_markup">False</property>
++ <property name="justify">GTK_JUSTIFY_LEFT</property>
++ <property name="wrap">False</property>
++ <property name="selectable">False</property>
++ <property name="xalign">0.5</property>
++ <property name="yalign">0.5</property>
++ <property name="xpad">0</property>
++ <property name="ypad">0</property>
++ <property name="mnemonic_widget">scrolledwindow1</property>
++ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
++ <property name="width_chars">-1</property>
++ <property name="single_line_mode">False</property>
++ <property name="angle">0</property>
++ </widget>
++ <packing>
++ <property name="padding">4</property>
++ <property name="expand">False</property>
++ <property name="fill">False</property>
++ </packing>
++ </child>
++
++ <child>
++ <placeholder/>
++ </child>
++
++ <child>
++ <placeholder/>
++ </child>
++ </widget>
++ <packing>
++ <property name="padding">0</property>
++ <property name="expand">False</property>
++ <property name="fill">False</property>
++ </packing>
++ </child>
++
++ <child>
++ <widget class="GtkScrolledWindow" id="scrolledwindow1">
++ <property name="visible">True</property>
++ <property name="can_focus">True</property>
++ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
++ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
++ <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
++ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
++
++ <child>
++ <widget class="GtkTreeView" id="tips_tree">
++ <property name="visible">True</property>
++ <property name="can_focus">True</property>
++ <property name="headers_visible">True</property>
++ <property name="rules_hint">False</property>
++ <property name="reorderable">False</property>
++ <property name="enable_search">True</property>
++ <property name="fixed_height_mode">False</property>
++ <property name="hover_selection">False</property>
++ <property name="hover_expand">False</property>
++ </widget>
++ </child>
++ </widget>
++ <packing>
++ <property name="padding">0</property>
++ <property name="expand">True</property>
++ <property name="fill">True</property>
++ </packing>
++ </child>
++
++ <child>
++ <widget class="GtkVBox" id="vbox26">
++ <property name="visible">True</property>
++ <property name="homogeneous">False</property>
++ <property name="spacing">0</property>
++
++ <child>
++ <placeholder/>
++ </child>
++
++ <child>
++ <widget class="GtkButton" id="add_to_tip_button">
++ <property name="visible">True</property>
++ <property name="can_default">True</property>
++ <property name="can_focus">True</property>
++ <property name="relief">GTK_RELIEF_NORMAL</property>
++ <property name="focus_on_click">True</property>
++
++ <child>
++ <widget class="GtkAlignment" id="alignment2">
++ <property name="visible">True</property>
++ <property name="xalign">0.5</property>
++ <property name="yalign">0.5</property>
++ <property name="xscale">0</property>
++ <property name="yscale">0</property>
++ <property name="top_padding">0</property>
++ <property name="bottom_padding">0</property>
++ <property name="left_padding">0</property>
++ <property name="right_padding">0</property>
++
++ <child>
++ <widget class="GtkHBox" id="hbox53">
++ <property name="visible">True</property>
++ <property name="homogeneous">False</property>
++ <property name="spacing">2</property>
++
++ <child>
++ <widget class="GtkImage" id="image2">
++ <property name="visible">True</property>
++ <property name="stock">gtk-add</property>
++ <property name="icon_size">4</property>
++ <property name="xalign">0.5</property>
++ <property name="yalign">0.5</property>
++ <property name="xpad">0</property>
++ <property name="ypad">0</property>
++ </widget>
++ <packing>
++ <property name="padding">0</property>
++ <property name="expand">False</property>
++ <property name="fill">False</property>
++ </packing>
++ </child>
++
++ <child>
++ <widget class="GtkLabel" id="label122">
++ <property name="visible">True</property>
++ <property name="label" translatable="yes">_Add</property>
++ <property name="use_underline">True</property>
++ <property name="use_markup">False</property>
++ <property name="justify">GTK_JUSTIFY_LEFT</property>
++ <property name="wrap">False</property>
++ <property name="selectable">False</property>
++ <property name="xalign">0.5</property>
++ <property name="yalign">0.5</property>
++ <property name="xpad">0</property>
++ <property name="ypad">0</property>
++ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
++ <property name="width_chars">-1</property>
++ <property name="single_line_mode">False</property>
++ <property name="angle">0</property>
++ </widget>
++ <packing>
++ <property name="padding">0</property>
++ <property name="expand">False</property>
++ <property name="fill">False</property>
++ </packing>
++ </child>
++ </widget>
++ </child>
++ </widget>
++ </child>
++ </widget>
++ <packing>
++ <property name="padding">0</property>
++ <property name="expand">False</property>
++ <property name="fill">True</property>
++ </packing>
++ </child>
++
++ <child>
++ <widget class="GtkLabel" id="label129">
++ <property name="visible">True</property>
++ <property name="label" translatable="yes"></property>
++ <property name="use_underline">False</property>
++ <property name="use_markup">False</property>
++ <property name="justify">GTK_JUSTIFY_LEFT</property>
++ <property name="wrap">False</property>
++ <property name="selectable">False</property>
++ <property name="xalign">0.5</property>
++ <property name="yalign">0.5</property>
++ <property name="xpad">0</property>
++ <property name="ypad">0</property>
++ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
++ <property name="width_chars">-1</property>
++ <property name="single_line_mode">False</property>
++ <property name="angle">0</property>
++ </widget>
++ <packing>
++ <property name="padding">0</property>
++ <property name="expand">False</property>
++ <property name="fill">False</property>
++ </packing>
++ </child>
++
++ <child>
++ <widget class="GtkButton" id="remove_from_tip_button">
++ <property name="visible">True</property>
++ <property name="can_default">True</property>
++ <property name="can_focus">True</property>
++ <property name="relief">GTK_RELIEF_NORMAL</property>
++ <property name="focus_on_click">True</property>
++
++ <child>
++ <widget class="GtkAlignment" id="alignment3">
++ <property name="visible">True</property>
++ <property name="xalign">0.5</property>
++ <property name="yalign">0.5</property>
++ <property name="xscale">0</property>
++ <property name="yscale">0</property>
++ <property name="top_padding">0</property>
++ <property name="bottom_padding">0</property>
++ <property name="left_padding">0</property>
++ <property name="right_padding">0</property>
++
++ <child>
++ <widget class="GtkHBox" id="hbox57">
++ <property name="visible">True</property>
++ <property name="homogeneous">False</property>
++ <property name="spacing">2</property>
++
++ <child>
++ <widget class="GtkImage" id="image3">
++ <property name="visible">True</property>
++ <property name="stock">gtk-remove</property>
++ <property name="icon_size">4</property>
++ <property name="xalign">0.5</property>
++ <property name="yalign">0.5</property>
++ <property name="xpad">0</property>
++ <property name="ypad">0</property>
++ </widget>
++ <packing>
++ <property name="padding">0</property>
++ <property name="expand">False</property>
++ <property name="fill">False</property>
++ </packing>
++ </child>
++
++ <child>
++ <widget class="GtkLabel" id="label124">
++ <property name="visible">True</property>
++ <property name="label" translatable="yes">_Remove</property>
++ <property name="use_underline">True</property>
++ <property name="use_markup">False</property>
++ <property name="justify">GTK_JUSTIFY_LEFT</property>
++ <property name="wrap">False</property>
++ <property name="selectable">False</property>
++ <property name="xalign">0.5</property>
++ <property name="yalign">0.5</property>
++ <property name="xpad">0</property>
++ <property name="ypad">0</property>
++ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
++ <property name="width_chars">-1</property>
++ <property name="single_line_mode">False</property>
++ <property name="angle">0</property>
++ </widget>
++ <packing>
++ <property name="padding">0</property>
++ <property name="expand">False</property>
++ <property name="fill">False</property>
++ </packing>
++ </child>
++ </widget>
++ </child>
++ </widget>
++ </child>
++ </widget>
++ <packing>
++ <property name="padding">0</property>
++ <property name="expand">True</property>
++ <property name="fill">False</property>
++ </packing>
++ </child>
++ </widget>
++ <packing>
++ <property name="padding">0</property>
++ <property name="expand">False</property>
++ <property name="fill">False</property>
++ <property name="pack_type">GTK_PACK_END</property>
++ </packing>
++ </child>
++ </widget>
++ <packing>
++ <property name="padding">0</property>
++ <property name="expand">True</property>
++ <property name="fill">True</property>
++ </packing>
++ </child>
++ </widget>
++ <packing>
++ <property name="padding">0</property>
++ <property name="expand">True</property>
++ <property name="fill">True</property>
++ </packing>
++ </child>
++ </widget>
++ </child>
++</widget>
++
++</glade-interface>
+diff -Nrup gnome-panel-2.14.1/applets/clock/tz.c ../gnome-panel-2.14.1/applets/clock/tz.c
+--- gnome-panel-2.14.1/applets/clock/tz.c 1970-01-01 01:00:00.000000000 +0100
++++ ../gnome-panel-2.14.1/applets/clock/tz.c 2006-06-12 16:18:42.719390000 +0200
+@@ -0,0 +1,499 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++/* Generic timezone utilities.
++ *
++ * Copyright (C) 2000-2001 Ximian, Inc.
++ * Copyright (C) 2004 Sun Microsystems, Inc.
++ *
++ * Authors: Hans Petter Jansson <[email protected]>
++ * additional functions by Erwann Chenede <[email protected]>
++ *
++ * Largely based on Michael Fulbright's work on Anaconda.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
++ */
++
++#include "tz.h"
++
++/* Forward declarations for private functions */
++
++static float convert_pos (gchar * pos, int digits);
++static int compare_country_names (const void *a, const void *b);
++static void sort_locations_by_country (GPtrArray * locations);
++static gchar *tz_data_file_get (void);
++
++extern char **environ;
++#ifdef HAVE_SOLARIS
++extern time_t timezone;
++extern char *tzname[2];
++#endif
++
++/* ---------------- *
++ * Public interface *
++ * ---------------- */
++
++struct tm *
++tz_get_localtime_at (const char *zone,
++ const time_t *now)
++{
++ char **environ_old;
++ char **envp;
++ struct tm *retval;
++ int i, env_len, tz_index;
++
++ tz_index = -1;
++ for (env_len = 0; environ [env_len]; env_len++)
++ if (!strncmp (environ [env_len], "TZ=", strlen ("TZ=")))
++ tz_index = env_len;
++
++ if (tz_index == -1)
++ tz_index = env_len++;
++
++ envp = g_new0 (char *, env_len + 1);
++
++ for (i = 0; i < env_len; i++)
++ if (i == tz_index)
++ envp [i] = g_strconcat ("TZ=", zone, NULL);
++ else
++ envp [i] = g_strdup (environ [i]);
++
++ environ_old = environ;
++ environ = envp;
++
++ retval = localtime (now);
++
++ environ = environ_old;
++ g_strfreev (envp);
++
++ return retval;
++}
++
++TzDB *
++tz_load_db (void)
++{
++ gchar *tz_data_file;
++ TzDB *tz_db;
++ FILE *tzfile;
++ char buf[4096];
++
++ tz_data_file = tz_data_file_get ();
++ if (!tz_data_file)
++ {
++ g_warning ("Could not get the TimeZone data file name");
++ return NULL;
++ }
++ tzfile = fopen (tz_data_file, "r");
++ if (!tzfile)
++ {
++ g_warning ("Could not open *%s*\n", tz_data_file);
++ g_free (tz_data_file);
++ return NULL;
++ }
++
++ tz_db = g_new0 (TzDB, 1);
++ tz_db->locations = g_ptr_array_new ();
++
++ while (fgets (buf, sizeof (buf), tzfile))
++ {
++ gchar **tmpstrarr;
++ gchar *latstr, *lngstr, *p;
++ TzLocation *loc;
++
++ if (*buf == '#')
++ continue;
++
++ g_strchomp (buf);
++ tmpstrarr = g_strsplit (buf, "\t", 4);
++
++ latstr = g_strdup (tmpstrarr[1]);
++ p = latstr + 1;
++ while (*p != '-' && *p != '+')
++ p++;
++ lngstr = g_strdup (p);
++ *p = '\0';
++
++ loc = g_new (TzLocation, 1);
++ loc->country = g_strdup (tmpstrarr[0]);
++ loc->zone = g_strdup (tmpstrarr[2]);
++ loc->comment = (tmpstrarr[3]) ? g_strdup (tmpstrarr[3]) : NULL;
++ loc->latitude = convert_pos (latstr, 2);
++ loc->longitude = convert_pos (lngstr, 3);
++
++ g_ptr_array_add (tz_db->locations, (gpointer) loc);
++
++ g_free (latstr);
++ g_free (lngstr);
++ g_strfreev (tmpstrarr);
++ }
++
++ fclose (tzfile);
++
++ /* now sort by country */
++ sort_locations_by_country (tz_db->locations);
++
++ /* added a NULL pointer at the end of the array to prevent errors. Carlos */
++ g_ptr_array_add (tz_db->locations, (gpointer) NULL);
++
++ g_free (tz_data_file);
++
++ return tz_db;
++}
++void
++tz_location_free (TzLocation * tz)
++{
++
++ if (tz->country)
++ g_free (tz->country);
++ if (tz->zone)
++ g_free (tz->zone);
++ if (tz->comment)
++ g_free (tz->comment);
++
++ g_free (tz);
++}
++
++void
++tz_free_db (TzDB *tz_db)
++{
++ int i;
++ for (i = 0; g_ptr_array_index (tz_db->locations, i); i++)
++ {
++ TzLocation *loc = g_ptr_array_index (tz_db->locations, i);
++ tz_location_free (loc);
++ }
++ g_ptr_array_free (tz_db->locations, FALSE);
++ g_free (tz_db);
++}
++
++GPtrArray *
++tz_get_locations (TzDB * db)
++{
++ return db->locations;
++}
++
++
++gchar *
++tz_location_get_country (TzLocation * loc)
++{
++ return loc->country;
++}
++
++
++gchar *
++tz_location_get_zone (TzLocation * loc)
++{
++ return loc->zone;
++}
++
++
++gchar *
++tz_location_get_comment (TzLocation * loc)
++{
++ return loc->comment;
++}
++
++
++void
++tz_location_get_position (TzLocation * loc, double *longitude,
++ double *latitude)
++{
++ *longitude = loc->longitude;
++ *latitude = loc->latitude;
++}
++
++
++
++
++TzInfo *
++tz_info_from_location (TzLocation * loc)
++{
++ TzInfo *tzinfo;
++ time_t curtime;
++ struct tm *curzone;
++
++ g_return_val_if_fail (loc != NULL, NULL);
++ g_return_val_if_fail (loc->zone != NULL, NULL);
++
++ tzinfo = g_new0 (TzInfo, 1);
++
++ curtime = time (NULL);
++ curzone = tz_get_localtime_at (loc->zone, &curtime);
++#if 0
++ g_print ("%s %s %d\n", curzone->tm_zone,
++ &curzone->tm_zone[curzone->tm_isdst], curzone->tm_isdst);
++#endif
++
++#ifdef HAVE_LINUX
++ tzinfo->tzname_normal = g_strdup (curzone->tm_zone);
++ if (curzone->tm_isdst)
++ tzinfo->tzname_daylight = g_strdup (&curzone->tm_zone[curzone->tm_isdst]);
++ else
++ tzinfo->tzname_daylight = NULL;
++
++ tzinfo->utc_offset = curzone->tm_gmtoff;
++#endif
++
++
++#ifdef HAVE_SOLARIS
++ tzinfo->tzname_normal = g_strdup (loc->zone);
++
++ if (curzone->tm_isdst)
++ tzinfo->tzname_daylight = g_strdup (tzname[0]);
++ else
++ tzinfo->tzname_daylight = NULL;
++
++ tzinfo->utc_offset -= (timezone - 3600);
++#endif
++ tzinfo->daylight = curzone->tm_isdst;
++
++ return tzinfo;
++}
++
++glong
++tz_location_get_utc_offset (TzLocation * loc)
++{
++ TzInfo *tz_info;
++ glong offset;
++
++ tz_info = tz_info_from_location (loc);
++ offset = tz_info->utc_offset;
++ tz_info_free (tz_info);
++ return offset;
++}
++
++void
++tz_info_free (TzInfo * tzinfo)
++{
++ g_return_if_fail (tzinfo != NULL);
++
++ if (tzinfo->tzname_normal)
++ g_free (tzinfo->tzname_normal);
++ if (tzinfo->tzname_daylight)
++ g_free (tzinfo->tzname_daylight);
++ g_free (tzinfo);
++}
++
++#ifdef HAVE_LINUX
++static gboolean
++find_from_inode (char *dir, int inode, char **filename)
++{
++ int num_dirent, i;
++ struct dirent **namelist;
++
++ num_dirent = scandir (dir, &namelist, 0, alphasort);
++
++ if (num_dirent == 0)
++ return FALSE;
++
++ for (i = 0; i < num_dirent; i++)
++ {
++ struct stat file_st;
++
++ if (strcmp (namelist[i]->d_name, ".") != 0 &&
++ strcmp (namelist[i]->d_name, "..") != 0)
++ {
++ char path[1024];
++
++ sprintf (path, "%s/%s", dir, namelist[i]->d_name);
++
++ if (stat (path, &file_st) == 0)
++ {
++
++ if (S_ISDIR (file_st.st_mode))
++ {
++ if (find_from_inode (path, inode, filename))
++ {
++ g_free (namelist);
++ return TRUE;
++ }
++ }
++ else if (inode == file_st.st_ino)
++ {
++ *filename = g_strdup (path);
++ g_free (namelist);
++ return TRUE;
++ }
++ }
++ else
++ {
++ g_free (namelist);
++ return FALSE;
++ }
++ }
++ }
++ g_free (namelist);
++ return FALSE;
++}
++#endif
++
++char *
++tz_get_system_timezone (void)
++{
++ struct stat st_clock, st_lt;
++
++ int fd, status;
++
++ char *tmpfilebuf, *tok_res, **toks, *file, *tz;
++
++ status = stat (SYS_CLOCK_FILE, &st_clock);
++
++ if (status == 0)
++ {
++ fd = open (SYS_CLOCK_FILE, O_RDONLY);
++
++ if (fd > 0)
++ {
++ tmpfilebuf = g_new (char, st_clock.st_size + 1);
++
++ status = read (fd, tmpfilebuf, st_clock.st_size);
++
++ close (fd);
++
++ if (status == st_clock.st_size)
++ {
++ tok_res = strstr (tmpfilebuf, ZONE_TOKEN);
++
++ if (tok_res) /* found timezone */
++ {
++ char *tz = NULL, **toks2;
++#ifdef HAVE_SOLARIS
++ toks = g_strsplit (tok_res, "\n", 3);
++
++ if (toks[0])
++ {
++ toks2 = g_strsplit (toks[0], ZONE_TOKEN, 3);
++ }
++ g_strfreev (toks);
++
++ tz = g_strdup (toks2[1]);
++#endif
++#ifdef HAVE_LINUX
++ toks = g_strsplit (tok_res, "\"", 3);
++
++ tz = g_strdup (toks[1]);
++ g_strfreev (toks);
++#endif
++ g_free (tmpfilebuf);
++ return tz;
++ }
++ }
++ }
++ }
++
++
++#ifdef HAVE_LINUX
++ /* the SYS_CLOCK_FILE didn't contain timezone info
++ * find the timezone from hard link LOCALTIME_FILE */
++
++ status = stat (LOCALTIME_FILE, &st_lt);
++
++ if (find_from_inode (ZONE_DIR, st_lt.st_ino, &file))
++ {
++ file += strlen (ZONE_DIR) + 1; /* +1 is for the / */
++
++ tz = g_strdup (file);
++ g_free (file);
++ return tz;
++ }
++#endif
++ return NULL;
++}
++
++
++/* ----------------- *
++ * Private functions *
++ * ----------------- */
++
++static gchar *
++tz_data_file_get (void)
++{
++ gchar *file;
++
++ file = g_strdup (TZ_DATA_FILE);
++
++ return file;
++}
++
++static float
++convert_pos (gchar * pos, int digits)
++{
++ gchar whole[10];
++ gchar *fraction;
++ gint i;
++ float t1, t2;
++
++ if (!pos || strlen (pos) < 4 || digits > 9)
++ return 0.0;
++
++ for (i = 0; i < digits + 1; i++)
++ whole[i] = pos[i];
++ whole[i] = '\0';
++ fraction = pos + digits + 1;
++
++ t1 = g_strtod (whole, NULL);
++ t2 = g_strtod (fraction, NULL);
++
++ if (t1 >= 0.0)
++ return t1 + t2 / pow (10.0, strlen (fraction));
++ else
++ return t1 - t2 / pow (10.0, strlen (fraction));
++}
++
++
++
++
++static int
++compare_country_names (const void *a, const void *b)
++{
++ const TzLocation *tza = *(TzLocation **) a;
++ const TzLocation *tzb = *(TzLocation **) b;
++
++ return strcmp (tza->zone, tzb->zone);
++}
++
++
++static void
++sort_locations_by_country (GPtrArray * locations)
++{
++ qsort (locations->pdata, locations->len, sizeof (gpointer),
++ compare_country_names);
++}
++
++TzLocation *
++tz_get_location_by_name (TzDB *tzdb, gchar * name)
++{
++ TzLocation *tz_loc = NULL;
++ GPtrArray *locs;
++ int i;
++
++ locs = tz_get_locations (tzdb);
++
++ for (i = 0; i < locs->len; i++)
++ {
++ TzLocation *tz_loc_temp;
++
++ tz_loc_temp = g_ptr_array_index (locs, i);
++
++ if (tz_loc_temp
++ && !g_utf8_collate (_(tz_location_get_zone (tz_loc_temp)), _(name)))
++ {
++ tz_loc = tz_loc_temp;
++ break;
++ }
++ }
++
++ return tz_loc;
++}
++
++
+diff -Nrup gnome-panel-2.14.1/applets/clock/tz.h ../gnome-panel-2.14.1/applets/clock/tz.h
+--- gnome-panel-2.14.1/applets/clock/tz.h 1970-01-01 01:00:00.000000000 +0100
++++ ../gnome-panel-2.14.1/applets/clock/tz.h 2006-06-12 16:18:42.719925000 +0200
+@@ -0,0 +1,114 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++/* Generic timezone utilities.
++ *
++ * Copyright (C) 2000-2001 Ximian, Inc.
++ * Copyright (C) 2004 Sun Microsystems, Inc.
++ *
++ * Authors: Hans Petter Jansson <[email protected]>
++ * Erwann Chenede <[email protected]>
++ *
++ *
++ * Largely based on Michael Fulbright's work on Anaconda.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
++ */
++
++
++#ifndef _E_TZ_H
++#define _E_TZ_H
++
++#include <glib.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include <time.h>
++#include <math.h>
++#include <string.h>
++#include <dirent.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <fcntl.h>
++#include <time.h>
++#include <config.h>
++#include <libgnome/libgnome.h>
++
++#ifdef HAVE_LINUX
++#define TZ_DATA_FILE "/usr/share/zoneinfo/zone.tab"
++#define ZONE_TOKEN "TIMEZONE=\""
++#define SYS_CLOCK_FILE "/etc/sysconfig/clock"
++#endif
++#ifdef HAVE_SOLARIS
++#define TZ_DATA_FILE "/usr/share/lib/zoneinfo/tab/zone_sun.tab"
++#define ZONE_TOKEN "TZ="
++#define SYS_CLOCK_FILE "/etc/TIMEZONE"
++#endif
++
++#define LOCALTIME_FILE "/etc/localtime"
++#define ZONE_DIR "/usr/share/zoneinfo"
++
++typedef struct _TzDB TzDB;
++typedef struct _TzLocation TzLocation;
++typedef struct _TzInfo TzInfo;
++
++
++struct _TzDB
++{
++ GPtrArray *locations;
++};
++
++struct _TzLocation
++{
++ gchar *country;
++ gdouble latitude;
++ gdouble longitude;
++ gchar *zone;
++ gchar *comment;
++};
++
++/* see the glibc info page information on time zone information */
++/* tzname_normal is the default name for the timezone */
++/* tzname_daylight is the name of the zone when in daylight savings */
++/* utc_offset is offset in seconds from utc */
++/* daylight if non-zero then location obeys daylight savings */
++
++struct _TzInfo
++{
++ gchar *tzname_normal;
++ gchar *tzname_daylight;
++ glong utc_offset;
++ gint daylight;
++};
++
++
++TzDB *tz_load_db (void);
++void tz_free_db (TzDB *tz_db);
++GPtrArray *tz_get_locations (TzDB *db);
++void tz_location_get_position (TzLocation *loc,
++ double *longitude, double *latitude);
++char *tz_location_get_country (TzLocation *loc);
++gchar *tz_location_get_zone (TzLocation *loc);
++gchar *tz_location_get_comment (TzLocation *loc);
++glong tz_location_get_utc_offset (TzLocation *loc);
++gint tz_location_set_locally (TzLocation *loc);
++TzInfo *tz_info_from_location (TzLocation *loc);
++void tz_info_free (TzInfo *tz_info);
++void tz_location_free (TzLocation *loc);
++struct tm *tz_get_localtime_at (const char *zone,
++ const time_t *now);
++char * tz_get_system_timezone (void);
++TzLocation * tz_get_location_by_name (TzDB *tzdb,
++ gchar * name);
++#endif
++
+diff -Nrup gnome-panel-2.14.1/config.h.in ../gnome-panel-2.14.1/config.h.in
+--- gnome-panel-2.14.1/config.h.in 2006-04-10 15:46:18.000000000 +0200
++++ ../gnome-panel-2.14.1/config.h.in 2006-06-12 16:18:40.872295000 +0200
+@@ -103,3 +103,6 @@
+
+ /* Define to 1 if the X Window System is missing or not being used. */
+ #undef X_DISPLAY_MISSING
++
++#undef HAVE_SOLARIS
++#undef HAVE_LINUX
+diff -Nrup gnome-panel-2.14.1/configure.in ../gnome-panel-2.14.1/configure.in
+--- gnome-panel-2.14.1/configure.in 2006-06-12 16:19:24.722615000 +0200
++++ ../gnome-panel-2.14.1/configure.in 2006-06-12 16:18:40.868184000 +0200
+@@ -97,7 +97,7 @@ if test -n "$LIBECAL_REQUIREMENT"; then
+ fi
+ AM_CONDITIONAL(HAVE_LIBECAL, test -n "$LIBECAL_REQUIREMENT")
+
+-PKG_CHECK_MODULES(CLOCK, gtk+-2.0 >= $GTK_REQUIRED libgnomeui-2.0 >= $LIBGNOMEUI_REQUIRED $LIBECAL_REQUIREMENT)
++PKG_CHECK_MODULES(CLOCK, gtk+-2.0 >= $GTK_REQUIRED libgnomeui-2.0 >= $LIBGNOMEUI_REQUIRED $LIBECAL_REQUIREMENT libglade-2.0 >= $LIBGLADE_REQUIRED)
+ AC_SUBST(CLOCK_CFLAGS)
+ AC_SUBST(CLOCK_LIBS)
+
+@@ -181,6 +181,18 @@ fi
+
+ AM_GCONF_SOURCE_2
+
++dnl platform test
++case $host in
++*-*-solaris*)
++ ostype=solaris
++ AC_DEFINE(HAVE_SOLARIS, 1, [Define to 1])
++ ;;
++*-*-linux*)
++ ostype=linux
++ AC_DEFINE(HAVE_LINUX, 1, [Define to 1])
++ ;;
++esac
++
+ dnl Don't use AC_PROG_AWK since we need the full pathname.
+ AC_PATH_PROGS(AWK, mawk gawk nawk awk, )
+ AC_PATH_PROGS(PERL, perl5 perl)
+@@ -208,6 +220,7 @@ libpanel-applet/Makefile
+ po/Makefile.in
+ applets/Makefile
+ applets/clock/Makefile
++applets/clock/e-map/Makefile
+ applets/notification_area/Makefile
+ applets/wncklet/Makefile
+ doc/Makefile
+--- gnome-panel-2.16.1.old/applets/clock/Makefile.am 2006-10-20 10:31:42.149737000 +0100
++++ gnome-panel-2.16.1/applets/clock/Makefile.am 2006-10-20 10:36:13.637552000 +0100
+@@ -1,3 +1,5 @@
++SUBDIRS = e-map
++
+ INCLUDES = \
+ -I$(srcdir)/../../libpanel-applet \
+ -I$(top_builddir)/libpanel-applet \
+@@ -6,6 +8,7 @@
+ $(WARN_CFLAGS) \
+ $(CLOCK_CFLAGS) \
+ -DDATADIR=\""$(datadir)"\" \
++ -DGLADEDIR=\""$(datadir)/gnome/panel/glade"\" \
+ -DLIBDIR=\""$(libdir)"\" \
+ -DSYSCONFDIR=\""$(sysconfdir)"\" \
+ -DPREFIX=\""$(prefix)"\" \
+@@ -20,10 +23,17 @@
+ calendar-debug.h
+ endif
+
+-CLOCK_SOURCES = clock.c $(CALENDAR_SOURCES)
++CLOCK_SOURCES = clock.c \
++ $(CALENDAR_SOURCES) \
++ tz.h \
++ tz.c \
++ clock.h \
++ timezone-selection.c \
++ multi-timezone.c
+
+ CLOCK_LDADD = \
+ ../../libpanel-applet/libpanel-applet-2.la \
++ e-map/libemap.a \
+ $(CLOCK_LIBS)
+
+ if CLOCK_INPROCESS
+@@ -46,6 +56,9 @@
+ clock_applet_CFLAGS =
+ endif
+
++gladedir = $(datadir)/gnome/panel/glade
++glade_DATA = timezone.glade
++
+ uidir = $(datadir)/gnome-2.0/ui
+ ui_DATA = GNOME_ClockApplet.xml
+
+--- gnome-panel-2.16.1.old/icons/Makefile.am 2006-10-20 10:31:41.032555000 +0100
++++ gnome-panel-2.16.1/icons/Makefile.am 2006-10-20 10:38:48.656881000 +0100
+@@ -6,6 +6,7 @@
+ gegl_DATA = \
+ gnome-gegl2-2.png \
+ gnome-gegl2.png \
++ world_map-960.png \
+ $(NULL)
+
+ EXTRA_DIST = $(gegl_DATA)
+--- gnome-panel-2.16.1.old/applets/clock/clock.c 2006-10-20 10:31:42.188005000 +0100
++++ gnome-panel-2.16.1/applets/clock/clock.c 2006-10-20 11:26:43.521255000 +0100
+@@ -27,6 +27,7 @@
+ * George Lebl
+ * Gediminas Paulauskas
+ * Mark McLoughlin
++ * Erwann Chenede
+ */
+
+ /*
+@@ -41,34 +42,9 @@
+
+ #include "config.h"
+
+-#include <stdio.h>
+-#include <sys/stat.h>
+-#include <unistd.h>
+-#include <dirent.h>
+-#include <string.h>
+-#include <time.h>
+-#include <langinfo.h>
+-
+-#include <panel-applet.h>
+-#include <panel-applet-gconf.h>
+-
+-#include <gtk/gtk.h>
+-#include <gdk/gdkkeysyms.h>
+-#include <gconf/gconf-client.h>
+-#include <libgnomeui/gnome-help.h>
+-#include <libgnomeui/gnome-url.h>
+-
+-#ifdef HAVE_LIBECAL
+-#include "calendar-client.h"
+-#endif
++#include "clock.h"
+
+ #define CLOCK_ICON "gnome-panel-clock"
+-#define INTERNETSECOND (864)
+-#define INTERNETBEAT (86400)
+-
+-#define N_GCONF_PREFS 7
+-
+-#define NEVER_SENSITIVE "never_sensitive"
+
+ static const char* KEY_FORMAT = "format";
+ static const char* KEY_SHOW_SECONDS = "show_seconds";
+@@ -77,6 +53,7 @@
+ static const char* KEY_CONFIG_TOOL = "config_tool";
+ static const char* KEY_CUSTOM_FORMAT = "custom_format";
+ static const char* KEY_SHOW_WEEK = "show_week_numbers";
++static const char* KEY_SHOW_ZONES = "show_zones";
+
+ static const char *clock_config_tools [] = {
+ "system-config-date",
+@@ -85,16 +62,6 @@
+ "time-admin",
+ };
+
+-/* Needs to match the indices in the combo */
+-typedef enum {
+- CLOCK_FORMAT_INVALID = 0,
+- CLOCK_FORMAT_12,
+- CLOCK_FORMAT_24,
+- CLOCK_FORMAT_UNIX,
+- CLOCK_FORMAT_INTERNET,
+- CLOCK_FORMAT_CUSTOM
+-} ClockFormat;
+-
+ static GConfEnumStringPair format_type_enum_map [] = {
+ { CLOCK_FORMAT_12, "12-hour" },
+ { CLOCK_FORMAT_24, "24-hour" },
+@@ -104,63 +71,6 @@
+ { 0, NULL }
+ };
+
+-typedef struct _ClockData ClockData;
+-
+-struct _ClockData {
+- /* widgets */
+- GtkWidget *applet;
+- GtkWidget *clockw;
+- GtkWidget *toggle;
+- GtkWidget *props;
+- GtkWidget *about;
+- GtkWidget *calendar_popup;
+- GtkWidget *calendar;
+-
+-#ifdef HAVE_LIBECAL
+- GtkWidget *task_list;
+- GtkWidget *appointment_list;
+-
+- GtkListStore *appointments_model;
+- GtkListStore *tasks_model;
+- GtkTreeModelFilter *tasks_filter;
+-
+- CalendarClient *client;
+-#endif /* HAVE_LIBECAL */
+-
+- /* preferences */
+- ClockFormat format;
+- char *custom_format;
+- gboolean showseconds;
+- gboolean showdate;
+- gboolean gmt_time;
+- gboolean showweek;
+-
+- char *config_tool;
+-
+- /* runtime data */
+- time_t current_time;
+- char *timeformat;
+- guint timeout;
+- PanelAppletOrient orient;
+- int size;
+- GtkAllocation old_allocation;
+-
+- int fixed_width;
+- int fixed_height;
+-
+- GtkWidget *showseconds_check;
+- GtkWidget *showdate_check;
+- GtkWidget *gmt_time_check;
+- GtkWidget *custom_hbox;
+- GtkWidget *custom_label;
+- GtkWidget *custom_entry;
+- gboolean custom_format_shown;
+-
+- gboolean can_handle_format_12;
+-
+- guint listeners [N_GCONF_PREFS];
+-};
+-
+ static void update_clock (ClockData * cd);
+ static float get_itime (time_t current_time);
+
+@@ -218,8 +128,8 @@
+ return width;
+ }
+
+-static void
+-set_tooltip (GtkWidget *applet,
++void
++clock_set_tooltip (GtkWidget *applet,
+ GtkWidget *widget,
+ const char *tip)
+ {
+@@ -445,6 +355,31 @@
+ update_orient (cd);
+ gtk_widget_queue_resize (cd->toggle);
+
++ /* multi timezone part */
++
++ if (cd->multizone_popup && cd->tip_list && GTK_WIDGET_MAPPED (cd->multizone_popup)) {
++ GSList *tmp_list;
++ char timeformat [128];
++ char *cr;
++
++ g_stpcpy (timeformat, cd->timeformat);
++ cr = g_strrstr (timeformat, "\n");
++ if (cr)
++ *cr = ' ';
++
++ for (tmp_list = cd->tip_list; tmp_list ; tmp_list = tmp_list->next) {
++ char tip_hour[256];
++ TipZone *tip_zone = tmp_list->data;
++
++ tm = tz_get_localtime_at (tip_zone->zone, &cd->current_time);
++
++ if (strftime (tip_hour, sizeof (tip_hour), timeformat, tm) <= 0)
++ strcpy (tip_hour, "???");
++
++ gtk_label_set_text (GTK_LABEL (tip_zone->time_label),
++ g_locale_to_utf8 (tip_hour, -1, NULL, NULL, NULL));
++ }
++
+ if (!cd->showdate) {
+ /* Show date in tooltip */
+ loc = g_locale_from_utf8 (_("%A %B %d"), -1, NULL, NULL, NULL);
+@@ -455,13 +390,13 @@
+ g_free (loc);
+
+ utf8 = g_locale_to_utf8 (date, -1, NULL, NULL, NULL);
+- set_tooltip (cd->applet, cd->toggle, utf8);
+- g_free (utf8);
++ clock_set_tooltip (cd->applet, cd->toggle, utf8);
++ }
+ } else {
+ #ifdef HAVE_LIBECAL
+- set_tooltip (cd->applet, cd->toggle, _("Click to view your appointments and tasks"));
++ clock_set_tooltip (cd->applet, cd->toggle, _("Click to view your appointments and tasks"));
+ #else
+- set_tooltip (cd->applet, cd->toggle, _("Click to view month calendar"));
++ clock_set_tooltip (cd->applet, cd->toggle, _("Click to view month calendar"));
+ #endif
+ }
+ }
+@@ -545,6 +480,14 @@
+ gtk_widget_destroy (cd->calendar_popup);
+ cd->calendar_popup = NULL;
+
++ if (cd->multizone_popup)
++ gtk_widget_destroy (cd->multizone_popup);
++ cd->multizone_popup = NULL;
++
++ if (cd->timezone_dialog)
++ gtk_widget_destroy (cd->timezone_dialog);
++ cd->timezone_dialog = NULL;
++
+ g_free (cd->timeformat);
+ g_free (cd->config_tool);
+ g_free (cd->custom_format);
+@@ -1599,12 +1542,46 @@
+ }
+
+ static void
++pop_timezones (ClockData *cd)
++{
++ GtkWidget *button = cd->multizone_toggle;
++
++ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button))) {
++ GtkWidget *calendar = g_object_get_data (G_OBJECT (button), "calendar");
++
++ if (!cd->multizone_popup) {
++ cd->multizone_popup = create_multi_timezones_popup (cd, gtk_widget_get_screen (cd->applet));
++ }
++
++ refresh_clock (cd);
++ gtk_widget_show_all (cd->multizone_popup);
++
++ if (calendar) {
++ gtk_widget_hide (calendar);
++ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cd->toggle), FALSE);
++ }
++
++ present_calendar_popup (cd, cd->multizone_popup, button);
++ } else {
++ if (cd->multizone_popup)
++ gtk_widget_hide (cd->multizone_popup);
++ }
++
++ update_clock (cd);
++}
++
++static void
+ update_popup (ClockData *cd)
+ {
++ GtkWindow *window;
++
++ window = g_object_get_data (G_OBJECT (cd->toggle), "calendar");
++
+ if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (cd->toggle))) {
+ if (cd->calendar_popup)
+ gtk_widget_destroy (cd->calendar_popup);
+ cd->calendar_popup = NULL;
++ g_object_set_data (G_OBJECT (cd->toggle), "calendar", NULL);
+ return;
+ }
+
+@@ -1612,9 +1589,14 @@
+ cd->calendar_popup = create_calendar (cd, gtk_widget_get_screen (cd->applet));
+ g_object_add_weak_pointer (G_OBJECT (cd->calendar_popup),
+ (gpointer *) &cd->calendar_popup);
++ g_object_set_data (G_OBJECT (cd->toggle), "calendar", cd->calendar_popup);
+ }
+
+ if (cd->calendar_popup && GTK_WIDGET_REALIZED (cd->toggle)) {
++ if (cd->multizone_popup) {
++ gtk_widget_hide (cd->multizone_popup);
++ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cd->multizone_toggle), FALSE);
++ }
+ #ifdef HAVE_LIBECAL
+ if (cd->tasks_filter && cd->task_list)
+ gtk_tree_model_filter_refilter (cd->tasks_filter);
+@@ -1626,6 +1608,12 @@
+ }
+
+ static void
++toggle_timezone (GtkWidget *button, ClockData *cd)
++{
++ pop_timezones (cd);
++}
++
++static void
+ toggle_calendar (GtkWidget *button,
+ ClockData *cd)
+ {
+@@ -1681,12 +1669,93 @@
+ }
+
+ static void
++change_clock_orientation (ClockData *cd)
++{
++ GtkWidget *box;
++
++ switch (cd->orient) {
++ case PANEL_APPLET_ORIENT_RIGHT:
++ case PANEL_APPLET_ORIENT_LEFT:
++ box = gtk_vbox_new (FALSE, 1);
++ break;
++ case PANEL_APPLET_ORIENT_DOWN:
++ case PANEL_APPLET_ORIENT_UP:
++ box = gtk_hbox_new (FALSE, 1);
++ break;
++ }
++
++ if (cd->hbox) {
++ gtk_widget_reparent (cd->multizone_toggle, box);
++ gtk_widget_reparent (cd->toggle, box);
++ gtk_container_remove (GTK_CONTAINER (cd->applet), cd->hbox);
++ } else {
++ gtk_container_add (GTK_CONTAINER (box), cd->multizone_toggle);
++ gtk_container_add (GTK_CONTAINER (box), cd->toggle);
++ }
++
++ cd->hbox = box;
++ gtk_container_add (GTK_CONTAINER (cd->applet), box);
++ gtk_widget_show_all (box);
++
++ if (!cd->show_multiple_timezones)
++ gtk_widget_hide (cd->multizone_toggle);
++}
++
++
++static void
++multizone_scale_image (GtkWidget *widget,
++ GtkAllocation *allocation,
++ ClockData *cd)
++{
++#define TOGGLE_BUTTON_BORDER 10
++ GdkPixbuf *pb;
++ int w, h, new_w, new_h;
++ gboolean need_to_scale = FALSE;
++ w = gdk_pixbuf_get_width (cd->image);
++ h = gdk_pixbuf_get_height (cd->image);
++
++ switch (cd->orient) {
++ case PANEL_APPLET_ORIENT_UP:
++ case PANEL_APPLET_ORIENT_DOWN:
++
++ if (cd->save_allocation_h != allocation->height) {
++ cd->save_allocation_h = allocation->height;
++ new_h = allocation->height - TOGGLE_BUTTON_BORDER;
++ new_w = (w * new_h) / h;
++ need_to_scale = TRUE;
++ }
++ break;
++ case PANEL_APPLET_ORIENT_RIGHT:
++ case PANEL_APPLET_ORIENT_LEFT:
++ if (cd->save_allocation_w != allocation->width) {
++ cd->save_allocation_w = allocation->width;
++ new_w = allocation->width - TOGGLE_BUTTON_BORDER;
++ new_h = (h * new_w) /w ;
++ need_to_scale = TRUE;
++ }
++ break;
++ }
++
++ if (need_to_scale) {
++ if (new_h < TOGGLE_BUTTON_BORDER)
++ new_h = TOGGLE_BUTTON_BORDER;
++ if (new_w < TOGGLE_BUTTON_BORDER)
++ new_w = TOGGLE_BUTTON_BORDER;
++
++ pb = gdk_pixbuf_scale_simple (cd->image, new_w, new_h, GDK_INTERP_HYPER);
++ gtk_image_set_from_pixbuf (GTK_IMAGE (cd->multizone_image), pb);
++ }
++}
++
++static void
+ create_clock_widget (ClockData *cd)
+ {
+ GtkWidget *clock;
+ GtkWidget *toggle;
+ GtkWidget *alignment;
++ GtkIconInfo *icon_info;
+
++ cd->orient = panel_applet_get_orient (PANEL_APPLET (cd->applet));
+ clock = gtk_label_new ("hmm?");
+ g_signal_connect (clock, "size_request",
+ G_CALLBACK (clock_size_request),
+@@ -1721,16 +1790,38 @@
+
+ cd->clockw = clock;
+
+- cd->props = NULL;
++ cd->size = panel_applet_get_size (PANEL_APPLET (cd->applet));
+
+- cd->orient = panel_applet_get_orient (PANEL_APPLET (cd->applet));
++ cd->multizone_toggle = gtk_toggle_button_new ();
++ gtk_container_set_resize_mode (GTK_CONTAINER (cd->multizone_toggle),
++ GTK_RESIZE_IMMEDIATE);
++ gtk_button_set_relief (GTK_BUTTON (cd->multizone_toggle), GTK_RELIEF_NONE);
++
++ icon_info = gtk_icon_theme_lookup_icon (gtk_icon_theme_get_default (), "stock_timezone", 48, 0);
++ cd->image = gtk_icon_info_load_icon (icon_info, NULL);
++ cd->multizone_image = gtk_image_new_from_pixbuf (cd->image);
++ gtk_icon_info_free (icon_info);
++ gtk_widget_show (cd->multizone_image);
++
++ gtk_container_add (GTK_CONTAINER (cd->multizone_toggle), cd->multizone_image);
++ gtk_widget_show (cd->multizone_toggle);
++
++ change_clock_orientation (cd);
++ cd->save_allocation_h = 0;
++ cd->save_allocation_w = 0;
+
+- cd->size = panel_applet_get_size (PANEL_APPLET (cd->applet));
++ cd->props = NULL;
+
+ g_signal_connect (G_OBJECT(clock), "destroy",
+ G_CALLBACK (destroy_clock),
+ cd);
+
++ g_signal_connect (cd->multizone_toggle, "toggled",
++ G_CALLBACK (toggle_timezone), cd);
++
++ g_signal_connect (cd->multizone_toggle, "size-allocate",
++ G_CALLBACK (multizone_scale_image), cd);
++
+ set_atk_name_description (GTK_WIDGET (cd->applet), NULL,
+ _("Computer Clock"));
+
+@@ -1779,6 +1870,7 @@
+ unfix_size (cd);
+ update_clock (cd);
+ update_popup (cd);
++ change_clock_orientation (cd);
+ }
+
+ /* this is when the panel size changes */
+@@ -1789,12 +1881,12 @@
+ {
+ int new_size;
+
+- if (cd->old_allocation.width == allocation->width &&
+- cd->old_allocation.height == allocation->height)
++ if (cd->save_allocation_w == allocation->width &&
++ cd->save_allocation_h == allocation->height)
+ return;
+
+- cd->old_allocation.width = allocation->width;
+- cd->old_allocation.height = allocation->height;
++ cd->save_allocation_w = allocation->width;
++ cd->save_allocation_h = allocation->height;
+
+ if (cd->orient == PANEL_APPLET_ORIENT_LEFT ||
+ cd->orient == PANEL_APPLET_ORIENT_RIGHT)
+@@ -2176,6 +2268,29 @@
+ }
+
+ static void
++show_multi_zones_changed (GConfClient *client,
++ guint cnxn_id,
++ GConfEntry *entry,
++ ClockData *clock)
++{
++ gboolean value;
++
++ if (!entry->value || entry->value->type != GCONF_VALUE_BOOL)
++ return;
++
++ value = gconf_value_get_bool (entry->value);
++
++ clock->show_multiple_timezones = (value != 0);
++
++ if (clock->show_multiple_timezones)
++ gtk_widget_show (clock->multizone_toggle);
++ else
++ gtk_widget_hide (clock->multizone_toggle);
++
++ refresh_clock (clock);
++}
++
++static void
+ setup_gconf (ClockData *clock)
+ {
+ GConfClient *client;
+@@ -2246,6 +2361,15 @@
+ clock, NULL, NULL);
+ g_free (key);
+
++ key = panel_applet_gconf_get_full_key (PANEL_APPLET (clock->applet),
++ KEY_SHOW_ZONES);
++ clock->listeners [7] =
++ gconf_client_notify_add (
++ client, key,
++ (GConfClientNotifyFunc) show_multi_zones_changed,
++ clock, NULL, NULL);
++ g_free (key);
++
+ g_object_unref (G_OBJECT (client));
+ }
+
+@@ -2342,10 +2466,8 @@
+
+ create_clock_widget (cd);
+
+- gtk_container_set_border_width (GTK_CONTAINER (cd->applet), 0);
+- gtk_container_set_border_width (GTK_CONTAINER (cd->toggle), 0);
+- gtk_container_add (GTK_CONTAINER (cd->applet), cd->toggle);
+-
++ cd->show_multiple_timezones = panel_applet_gconf_get_bool (applet, KEY_SHOW_ZONES, NULL);
++
+ #ifndef CLOCK_INPROCESS
+ gtk_window_set_default_icon_name (CLOCK_ICON);
+ #endif
+@@ -2519,6 +2641,16 @@
+ }
+
+ static void
++set_show_zones_cb (GtkWidget *w,
++ ClockData *clock)
++{
++ panel_applet_gconf_set_bool (PANEL_APPLET (clock->applet),
++ KEY_SHOW_ZONES,
++ GTK_TOGGLE_BUTTON (w)->active,
++ NULL);
++}
++
++static void
+ set_show_seconds_cb (GtkWidget *w,
+ ClockData *clock)
+ {
+@@ -2709,6 +2841,15 @@
+ cd);
+ gtk_widget_show (cd->gmt_time_check);
+
++ cd->showzones_check = gtk_check_button_new_with_mnemonic (_("Show _time zones button"));
++ gtk_box_pack_start (GTK_BOX (vbox), cd->showzones_check, FALSE, FALSE, 0);
++ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cd->showzones_check),
++ cd->show_multiple_timezones);
++ g_signal_connect (G_OBJECT (cd->showzones_check), "toggled",
++ G_CALLBACK (set_show_zones_cb),
++ cd);
++ gtk_widget_show (cd->showzones_check);
++
+ g_signal_connect (cd->props, "destroy",
+ G_CALLBACK (gtk_widget_destroyed),
+ &cd->props);
+@@ -2781,6 +2922,7 @@
+ {
+ "George Lebl <[email protected]>",
+ "Gediminas Paulauskas <[email protected]>",
++ "multi time zone Erwann Chenede",
+ NULL
+ };
+ static const char *documenters[] =
--- a/patches/gnome-panel-10-solaris-branding.diff Fri Oct 20 15:24:25 2006 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
---- gnome-panel-2.16.0/gnome-panel/panel-menu-button.c 2006-09-21 16:21:12.547123000 +0200
-+++ ../gnome-panel-2.16.0/gnome-panel/panel-menu-button.c 2006-09-21 16:15:16.549802000 +0200
-@@ -692,7 +692,7 @@
- "tooltip", tooltip,
- "use-menu-path", use_menu_path,
- "use-custom-icon", use_custom_icon,
-- "has-arrow", TRUE,
-+ "has-arrow", FALSE,
- NULL);
-
- info = panel_applet_register (GTK_WIDGET (button), NULL, NULL,
-@@ -772,7 +772,23 @@
- }
-
- if (!retval)
-- retval = g_strdup (PANEL_MAIN_MENU_ICON);
-+ {
-+ static gboolean inited = FALSE;
-+ static gboolean has_sun_branding = FALSE;
-+
-+ if (!inited)
-+ {
-+ GtkIconTheme *theme = gtk_icon_theme_get_default ();
-+ if (gtk_icon_theme_has_icon (theme, "sun-start-here"))
-+ has_sun_branding = TRUE;
-+ inited = TRUE;
-+ }
-+
-+ if (has_sun_branding)
-+ retval = g_strdup ("sun-start-here");
-+ else
-+ retval = g_strdup (PANEL_MAIN_MENU_ICON);
-+ }
-
- return retval;
- }
--- a/patches/gnome-panel-11-clock-timezone.diff Fri Oct 20 15:24:25 2006 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,5191 +0,0 @@
-diff -Nrup gnome-panel-2.14.1/applets/clock/clock.h ../gnome-panel-2.14.1/applets/clock/clock.h
---- gnome-panel-2.14.1/applets/clock/clock.h 1970-01-01 01:00:00.000000000 +0100
-+++ ../gnome-panel-2.14.1/applets/clock/clock.h 2006-06-12 16:18:42.518645000 +0200
-@@ -0,0 +1,176 @@
-+#ifndef __CLOCK_H__
-+#define __CLOCK_H__
-+
-+#include <stdio.h>
-+#include <sys/stat.h>
-+#include <unistd.h>
-+#include <dirent.h>
-+#include <string.h>
-+#include <time.h>
-+#include <langinfo.h>
-+
-+#include <panel-applet.h>
-+#include <panel-applet-gconf.h>
-+
-+#include <gtk/gtk.h>
-+#include <gdk/gdkkeysyms.h>
-+#include <libbonobo.h>
-+#include <gconf/gconf-client.h>
-+#include <libgnomeui/gnome-help.h>
-+#include <libgnome/gnome-init.h>
-+#include <libgnomeui/gnome-url.h>
-+
-+#include <glade/glade.h>
-+
-+#ifdef HAVE_LIBECAL
-+#include "calendar-client.h"
-+#endif
-+#include "tz.h"
-+#include "e-map/e-map.h"
-+
-+#define INTERNETSECOND (864)
-+#define INTERNETBEAT (86400)
-+
-+#define N_GCONF_PREFS 8
-+
-+#define NEVER_SENSITIVE "never_sensitive"
-+
-+typedef struct _ClockData ClockData;
-+typedef struct _TimezoneSelectionDialog TimezoneSelectionDialog;
-+typedef struct _TipZone TipZone;
-+
-+typedef enum {
-+ CLOCK_FORMAT_INVALID = 0,
-+ CLOCK_FORMAT_12,
-+ CLOCK_FORMAT_24,
-+ CLOCK_FORMAT_UNIX,
-+ CLOCK_FORMAT_INTERNET,
-+ CLOCK_FORMAT_CUSTOM
-+} ClockFormat;
-+
-+struct _ClockData {
-+ /* widgets */
-+ GtkWidget *applet;
-+ GtkWidget *clockw;
-+ GtkWidget *toggle;
-+ GtkWidget *props;
-+ GtkWidget *about;
-+ GtkWidget *calendar_popup;
-+ GtkWidget *calendar;
-+ GtkWidget *timezone_dialog;
-+ GtkWidget *multizone_popup;
-+
-+
-+ GtkWidget *hbox;
-+
-+ GtkWidget *multizone_toggle;
-+ GtkWidget *multizone_image;
-+ GdkPixbuf *image;
-+
-+#ifdef HAVE_LIBECAL
-+ GtkWidget *task_list;
-+ GtkWidget *appointment_list;
-+
-+ GtkListStore *appointments_model;
-+ GtkListStore *tasks_model;
-+ GtkTreeModelFilter *tasks_filter;
-+
-+ CalendarClient *client;
-+#endif /* HAVE_LIBECAL */
-+
-+ /* preferences */
-+ ClockFormat format;
-+ char *custom_format;
-+ gboolean showseconds;
-+ gboolean showdate;
-+ gboolean gmt_time;
-+ gboolean showweek;
-+ gboolean show_multiple_timezones;
-+
-+ char *config_tool;
-+
-+ /* runtime data */
-+ time_t current_time;
-+ char *timeformat;
-+ guint timeout;
-+ PanelAppletOrient orient;
-+ int size;
-+ int save_allocation_h;
-+ int save_allocation_w;
-+
-+ TimezoneSelectionDialog *tsd;
-+ GSList *tip_list;
-+ TzDB *tzdb;
-+
-+ int fixed_width;
-+ int fixed_height;
-+
-+ GtkWidget *showseconds_check;
-+ GtkWidget *showdate_check;
-+ GtkWidget *gmt_time_check;
-+ GtkWidget *custom_hbox;
-+ GtkWidget *custom_label;
-+ GtkWidget *custom_entry;
-+ GtkWidget *showzones_check;
-+ gboolean custom_format_shown;
-+
-+ gboolean can_handle_format_12;
-+
-+ guint listeners [N_GCONF_PREFS];
-+};
-+
-+void
-+clock_set_tooltip (GtkWidget *applet,
-+ GtkWidget *widget,
-+ const char *tip);
-+
-+
-+#define TZ_MAP_POINT_NORMAL_RGBA 0xc070a0ff
-+#define TZ_MAP_POINT_HOVER_RGBA 0xffff60ff
-+#define TZ_MAP_POINT_SELECTED_1_RGBA 0xff60e0ff
-+#define TZ_MAP_POINT_SELECTED_2_RGBA 0x000000ff
-+
-+
-+struct _TimezoneSelectionDialog
-+{
-+ GtkWidget *dialog;
-+ GladeXML *xml;
-+
-+ EMapPoint *point_selected;
-+ EMapPoint *point_hover;
-+ EMap *map;
-+ glong correction;
-+ char *zone;
-+
-+ guint timeout;
-+
-+ /* multi timezone part */
-+ GtkWidget *tips_tree;
-+ GtkTreeStore *model;
-+
-+ ClockData *cd;
-+};
-+
-+void
-+display_timezone_selection_dialog (BonoboUIComponent *uic,
-+ ClockData *cd,
-+ const gchar *verbname);
-+
-+/* multi-timezone part */
-+
-+
-+struct _TipZone {
-+ char *zone;
-+ char *nick;
-+ GtkWidget *time_label;
-+ GtkWidget *nick_label;
-+};
-+
-+GtkWidget * create_multi_timezones_popup (ClockData *cd,
-+ GdkScreen *screen);
-+void create_multizone_table (TimezoneSelectionDialog *tsd);
-+void timzone_dialog_set_zones_only (TimezoneSelectionDialog *tsd);
-+void timzone_dialog_set_main_zone_only (TimezoneSelectionDialog *tsd);
-+gboolean multizone_is_zone_in_tip_list (ClockData *cd, char *zone);
-+#endif /* __CLOCK_H__ */
-+
-diff -Nrup gnome-panel-2.14.1/applets/clock/clock.schemas.in ../gnome-panel-2.14.1/applets/clock/clock.schemas.in
---- gnome-panel-2.14.1/applets/clock/clock.schemas.in 2006-06-12 16:19:24.709455000 +0200
-+++ ../gnome-panel-2.14.1/applets/clock/clock.schemas.in 2006-06-12 16:18:42.506318000 +0200
-@@ -174,6 +174,18 @@
- </locale>
- </schema>
-
-+ <schema>
-+ <key>/schemas/apps/clock_applet/prefs/show_zones</key>
-+ <owner>clock-applet</owner>
-+ <type>bool</type>
-+ <default>false</default>
-+ <locale name="C">
-+ <short>Show the timezone button</short>
-+ <long>If true, display the timezone button in the clock, in addition to time.</long>
-+ </locale>
-+ </schema>
-+
-+
- </schemalist>
-
- </gconfschemafile>
-diff -Nrup gnome-panel-2.14.1/applets/clock/e-map/Makefile.am ../gnome-panel-2.14.1/applets/clock/e-map/Makefile.am
---- gnome-panel-2.14.1/applets/clock/e-map/Makefile.am 1970-01-01 01:00:00.000000000 +0100
-+++ ../gnome-panel-2.14.1/applets/clock/e-map/Makefile.am 2006-06-12 16:18:42.525973000 +0200
-@@ -0,0 +1,32 @@
-+INCLUDES = \
-+ -DPACKAGE_DATA_DIR=\""$(datadir)/gnome/panel/pixmaps"\" \
-+ -DPACKAGE_LOCALE_DIR=\""$(prefix)/$(DATADIRNAME)/locale"\" \
-+ $(WARN_CFLAGS) \
-+ $(FISH_CFLAGS)
-+
-+EXTRA_DIST= e-map-marshal.list
-+
-+e-map-marshal.h: e-map-marshal.list
-+ ( @GLIB_GENMARSHAL@ e-map-marshal.list --header > e-map-marshal.tmp \
-+ && mv e-map-marshal.tmp e-map-marshal.h ) \
-+ || ( rm -f e-map-marshal.tmp && exit 1 )
-+
-+e-map-marshal.c: e-map-marshal.h
-+ ( @GLIB_GENMARSHAL@ e-map-marshal.list --body > e-map-marshal.tmp \
-+ && mv e-map-marshal.tmp e-map-marshal.c ) \
-+ || ( rm -f e-map-marshal.tmp && exit 1 )
-+
-+$(e_map_la_OBJECTS): e-map-marshal.h
-+
-+noinst_LIBRARIES = libemap.a
-+
-+libemap_a_CFLAGS = \
-+ $(GNOME_CFLAGS) \
-+ $(GDK_PIXBUF_CFLAGS)
-+
-+BUILT_SOURCES= e-map-marshal.c e-map-marshal.h
-+
-+libemap_a_SOURCES = \
-+ e-map.c e-map.h \
-+ e-map-marshal.c e-map-marshal.h
-+
-diff -Nrup gnome-panel-2.14.1/applets/clock/e-map/e-map-marshal.c ../gnome-panel-2.14.1/applets/clock/e-map/e-map-marshal.c
---- gnome-panel-2.14.1/applets/clock/e-map/e-map-marshal.c 1970-01-01 01:00:00.000000000 +0100
-+++ ../gnome-panel-2.14.1/applets/clock/e-map/e-map-marshal.c 2006-06-12 16:18:42.714593000 +0200
-@@ -0,0 +1,86 @@
-+
-+#include <glib-object.h>
-+
-+
-+#ifdef G_ENABLE_DEBUG
-+#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v)
-+#define g_marshal_value_peek_char(v) g_value_get_char (v)
-+#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v)
-+#define g_marshal_value_peek_int(v) g_value_get_int (v)
-+#define g_marshal_value_peek_uint(v) g_value_get_uint (v)
-+#define g_marshal_value_peek_long(v) g_value_get_long (v)
-+#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v)
-+#define g_marshal_value_peek_int64(v) g_value_get_int64 (v)
-+#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v)
-+#define g_marshal_value_peek_enum(v) g_value_get_enum (v)
-+#define g_marshal_value_peek_flags(v) g_value_get_flags (v)
-+#define g_marshal_value_peek_float(v) g_value_get_float (v)
-+#define g_marshal_value_peek_double(v) g_value_get_double (v)
-+#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v)
-+#define g_marshal_value_peek_param(v) g_value_get_param (v)
-+#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v)
-+#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v)
-+#define g_marshal_value_peek_object(v) g_value_get_object (v)
-+#else /* !G_ENABLE_DEBUG */
-+/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API.
-+ * Do not access GValues directly in your code. Instead, use the
-+ * g_value_get_*() functions
-+ */
-+#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int
-+#define g_marshal_value_peek_char(v) (v)->data[0].v_int
-+#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint
-+#define g_marshal_value_peek_int(v) (v)->data[0].v_int
-+#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint
-+#define g_marshal_value_peek_long(v) (v)->data[0].v_long
-+#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong
-+#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64
-+#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64
-+#define g_marshal_value_peek_enum(v) (v)->data[0].v_long
-+#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong
-+#define g_marshal_value_peek_float(v) (v)->data[0].v_float
-+#define g_marshal_value_peek_double(v) (v)->data[0].v_double
-+#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer
-+#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer
-+#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer
-+#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer
-+#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer
-+#endif /* !G_ENABLE_DEBUG */
-+
-+
-+/* VOID:OBJECT,OBJECT (e-map-marshal.list:1) */
-+void
-+g_cclosure_user_marshal_VOID__OBJECT_OBJECT (GClosure *closure,
-+ GValue *return_value,
-+ guint n_param_values,
-+ const GValue *param_values,
-+ gpointer invocation_hint,
-+ gpointer marshal_data)
-+{
-+ typedef void (*GMarshalFunc_VOID__OBJECT_OBJECT) (gpointer data1,
-+ gpointer arg_1,
-+ gpointer arg_2,
-+ gpointer data2);
-+ register GMarshalFunc_VOID__OBJECT_OBJECT callback;
-+ register GCClosure *cc = (GCClosure*) closure;
-+ register gpointer data1, data2;
-+
-+ g_return_if_fail (n_param_values == 3);
-+
-+ if (G_CCLOSURE_SWAP_DATA (closure))
-+ {
-+ data1 = closure->data;
-+ data2 = g_value_peek_pointer (param_values + 0);
-+ }
-+ else
-+ {
-+ data1 = g_value_peek_pointer (param_values + 0);
-+ data2 = closure->data;
-+ }
-+ callback = (GMarshalFunc_VOID__OBJECT_OBJECT) (marshal_data ? marshal_data : cc->callback);
-+
-+ callback (data1,
-+ g_marshal_value_peek_object (param_values + 1),
-+ g_marshal_value_peek_object (param_values + 2),
-+ data2);
-+}
-+
-diff -Nrup gnome-panel-2.14.1/applets/clock/e-map/e-map-marshal.h ../gnome-panel-2.14.1/applets/clock/e-map/e-map-marshal.h
---- gnome-panel-2.14.1/applets/clock/e-map/e-map-marshal.h 1970-01-01 01:00:00.000000000 +0100
-+++ ../gnome-panel-2.14.1/applets/clock/e-map/e-map-marshal.h 2006-06-12 16:18:42.529818000 +0200
-@@ -0,0 +1,20 @@
-+
-+#ifndef __g_cclosure_user_marshal_MARSHAL_H__
-+#define __g_cclosure_user_marshal_MARSHAL_H__
-+
-+#include <glib-object.h>
-+
-+G_BEGIN_DECLS
-+
-+/* VOID:OBJECT,OBJECT (e-map-marshal.list:1) */
-+extern void g_cclosure_user_marshal_VOID__OBJECT_OBJECT (GClosure *closure,
-+ GValue *return_value,
-+ guint n_param_values,
-+ const GValue *param_values,
-+ gpointer invocation_hint,
-+ gpointer marshal_data);
-+
-+G_END_DECLS
-+
-+#endif /* __g_cclosure_user_marshal_MARSHAL_H__ */
-+
-diff -Nrup gnome-panel-2.14.1/applets/clock/e-map/e-map-marshal.list ../gnome-panel-2.14.1/applets/clock/e-map/e-map-marshal.list
---- gnome-panel-2.14.1/applets/clock/e-map/e-map-marshal.list 1970-01-01 01:00:00.000000000 +0100
-+++ ../gnome-panel-2.14.1/applets/clock/e-map/e-map-marshal.list 2006-06-12 16:18:42.525751000 +0200
-@@ -0,0 +1 @@
-+VOID:OBJECT,OBJECT
-diff -Nrup gnome-panel-2.14.1/applets/clock/e-map/e-map.c ../gnome-panel-2.14.1/applets/clock/e-map/e-map.c
---- gnome-panel-2.14.1/applets/clock/e-map/e-map.c 1970-01-01 01:00:00.000000000 +0100
-+++ ../gnome-panel-2.14.1/applets/clock/e-map/e-map.c 2006-06-12 16:18:42.527048000 +0200
-@@ -0,0 +1,1789 @@
-+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-+/* Map widget.
-+ *
-+ * Copyright (C) 2000-2001 Ximian, Inc.
-+ *
-+ * Authors: Hans Petter Jansson <[email protected]>
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of version 2 of the GNU General Public
-+ * License as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public
-+ * License along with this program; if not, write to the
-+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ * Boston, MA 02111-1307, USA.
-+ */
-+
-+#include <config.h>
-+#include <math.h>
-+#include <stdlib.h>
-+#include <gdk/gdkkeysyms.h>
-+#include <gtk/gtksignal.h>
-+#include <gdk-pixbuf/gdk-pixbuf.h>
-+#include <libart_lgpl/art_filterlevel.h>
-+
-+#include "e-map.h"
-+
-+/* Scroll step increment */
-+
-+#define SCROLL_STEP_SIZE 32
-+
-+
-+/* */
-+
-+#define E_MAP_GET_WIDTH(map) gdk_pixbuf_get_width(((EMapPrivate *) E_MAP(map)->priv)->map_render_pixbuf)
-+#define E_MAP_GET_HEIGHT(map) gdk_pixbuf_get_height(((EMapPrivate *) E_MAP(map)->priv)->map_render_pixbuf)
-+
-+
-+/* Zoom state - keeps track of animation hacks */
-+
-+typedef enum
-+{
-+ E_MAP_ZOOMED_IN,
-+ E_MAP_ZOOMED_OUT,
-+ E_MAP_ZOOMING_IN,
-+ E_MAP_ZOOMING_OUT
-+}
-+EMapZoomState;
-+
-+
-+/* Private part of the EMap structure */
-+
-+typedef struct
-+{
-+ /* Pointer to map image */
-+ GdkPixbuf *map_pixbuf, *map_render_pixbuf;
-+
-+ /* Settings */
-+ gboolean frozen, smooth_zoom;
-+
-+ /* Adjustments for scrolling */
-+ GtkAdjustment *hadj;
-+ GtkAdjustment *vadj;
-+
-+ /* Current scrolling offsets */
-+ int xofs, yofs;
-+
-+ /* Realtime zoom data */
-+ EMapZoomState zoom_state;
-+ double zoom_target_long, zoom_target_lat;
-+
-+ /* Dots */
-+ GPtrArray *points;
-+}
-+EMapPrivate;
-+
-+
-+/* Internal prototypes */
-+
-+static void e_map_class_init (EMapClass *class);
-+static void e_map_init (EMap *view);
-+static void e_map_finalize (GObject *object);
-+static void e_map_destroy (GtkObject *object);
-+static void e_map_unmap (GtkWidget *widget);
-+static void e_map_realize (GtkWidget *widget);
-+static void e_map_unrealize (GtkWidget *widget);
-+static void e_map_size_request (GtkWidget *widget, GtkRequisition *requisition);
-+static void e_map_size_allocate (GtkWidget *widget, GtkAllocation *allocation);
-+static gint e_map_button_press (GtkWidget *widget, GdkEventButton *event);
-+static gint e_map_button_release (GtkWidget *widget, GdkEventButton *event);
-+static gint e_map_motion (GtkWidget *widget, GdkEventMotion *event);
-+static gint e_map_expose (GtkWidget *widget, GdkEventExpose *event);
-+static gint e_map_key_press (GtkWidget *widget, GdkEventKey *event);
-+static void e_map_set_scroll_adjustments (GtkWidget *widget, GtkAdjustment *hadj, GtkAdjustment *vadj);
-+
-+static void update_render_pixbuf (EMap *map, ArtFilterLevel interp, gboolean render_overlays);
-+static void set_scroll_area (EMap *view);
-+static void request_paint_area (EMap *view, GdkRectangle *area);
-+static void center_at (EMap *map, int x, int y, gboolean scroll);
-+static void smooth_center_at (EMap *map, int x, int y);
-+static void scroll_to (EMap *view, int x, int y);
-+static void zoom_do (EMap *map);
-+static gint load_map_background (EMap *view, gchar *name);
-+static void adjustment_changed_cb (GtkAdjustment *adj, gpointer data);
-+static void update_and_paint (EMap *map);
-+static void update_render_point (EMap *map, EMapPoint *point);
-+static void repaint_point (EMap *map, EMapPoint *point);
-+
-+static GtkWidgetClass *parent_class;
-+
-+
-+/* ----------------- *
-+ * Widget management *
-+ * ----------------- */
-+
-+
-+/**
-+ * e_map_get_type:
-+ * @void:
-+ *
-+ * Registers the #EMap class if necessary, and returns the type ID
-+ * associated to it.
-+ *
-+ * Return value: The type ID of the #EMap class.
-+ **/
-+
-+GtkType
-+e_map_get_type (void)
-+{
-+ static GtkType e_map_type = 0;
-+
-+ if (!e_map_type)
-+ {
-+ static const GtkTypeInfo e_map_info =
-+ {
-+ "EMap",
-+ sizeof (EMap),
-+ sizeof (EMapClass),
-+ (GtkClassInitFunc) e_map_class_init,
-+ (GtkObjectInitFunc) e_map_init,
-+ NULL, /* reserved_1 */
-+ NULL, /* reserved_2 */
-+ (GtkClassInitFunc) NULL
-+ };
-+
-+ e_map_type = gtk_type_unique (GTK_TYPE_WIDGET, &e_map_info);
-+ }
-+
-+ return e_map_type;
-+}
-+
-+/* Class initialization function for the map view */
-+
-+static void
-+e_map_class_init (EMapClass *class)
-+{
-+ GObjectClass *gobject_class;
-+ GtkObjectClass *object_class;
-+ GtkWidgetClass *widget_class;
-+
-+ gobject_class = (GObjectClass *) class;
-+ object_class = (GtkObjectClass *) class;
-+ widget_class = (GtkWidgetClass *) class;
-+
-+ parent_class = g_type_class_ref(GTK_TYPE_WIDGET);
-+
-+ gobject_class->finalize = e_map_finalize;
-+
-+ object_class->destroy = e_map_destroy;
-+
-+ class->set_scroll_adjustments = e_map_set_scroll_adjustments;
-+ widget_class->set_scroll_adjustments_signal = gtk_signal_new ("set_scroll_adjustments",
-+ GTK_RUN_LAST,
-+ GTK_CLASS_TYPE (object_class),
-+ G_STRUCT_OFFSET (EMapClass, set_scroll_adjustments),
-+ gtk_marshal_NONE__POINTER_POINTER,
-+ GTK_TYPE_NONE, 2,
-+ GTK_TYPE_ADJUSTMENT,
-+ GTK_TYPE_ADJUSTMENT);
-+
-+ widget_class->unmap = e_map_unmap;
-+ widget_class->realize = e_map_realize;
-+ widget_class->unrealize = e_map_unrealize;
-+ widget_class->size_request = e_map_size_request;
-+ widget_class->size_allocate = e_map_size_allocate;
-+ widget_class->button_press_event = e_map_button_press;
-+ widget_class->button_release_event = e_map_button_release;
-+ widget_class->motion_notify_event = e_map_motion;
-+ widget_class->expose_event = e_map_expose;
-+ widget_class->key_press_event = e_map_key_press;
-+}
-+
-+
-+/* Object initialization function for the map view */
-+
-+static void
-+e_map_init (EMap *view)
-+{
-+ EMapPrivate *priv;
-+
-+ priv = g_new0 (EMapPrivate, 1);
-+ view->priv = priv;
-+
-+ load_map_background (view, PACKAGE_DATA_DIR"/world_map-960.png");
-+ priv->frozen = FALSE;
-+ priv->smooth_zoom = TRUE;
-+ priv->zoom_state = E_MAP_ZOOMED_OUT;
-+ priv->points = g_ptr_array_new ();
-+
-+ GTK_WIDGET_SET_FLAGS (view, GTK_CAN_FOCUS);
-+ GTK_WIDGET_UNSET_FLAGS (view, GTK_NO_WINDOW);
-+}
-+
-+
-+/* Destroy handler for the map view */
-+
-+static void
-+e_map_destroy (GtkObject *object)
-+{
-+ EMap *view;
-+ EMapPrivate *priv;
-+
-+ g_return_if_fail (object != NULL);
-+ g_return_if_fail (IS_E_MAP (object));
-+
-+ view = E_MAP (object);
-+ priv = view->priv;
-+
-+ g_signal_handlers_disconnect_by_func (priv->hadj, adjustment_changed_cb, view);
-+ g_signal_handlers_disconnect_by_func (priv->vadj, adjustment_changed_cb, view);
-+
-+ if (GTK_OBJECT_CLASS (parent_class)->destroy)
-+ (*GTK_OBJECT_CLASS (parent_class)->destroy) (object);
-+}
-+
-+
-+/* Finalize handler for the map view */
-+
-+static void
-+e_map_finalize (GObject *object)
-+{
-+ EMap *view;
-+ EMapPrivate *priv;
-+
-+ g_return_if_fail (object != NULL);
-+ g_return_if_fail (IS_E_MAP (object));
-+
-+ view = E_MAP (object);
-+ priv = view->priv;
-+
-+ g_object_unref((priv->hadj));
-+ priv->hadj = NULL;
-+
-+ g_object_unref((priv->vadj));
-+ priv->vadj = NULL;
-+
-+ if (priv->map_pixbuf)
-+ {
-+ g_object_unref (priv->map_pixbuf);
-+ priv->map_pixbuf = NULL;
-+ }
-+
-+ if (priv->map_render_pixbuf)
-+ {
-+ g_object_unref (priv->map_render_pixbuf);
-+ priv->map_render_pixbuf = NULL;
-+ }
-+
-+ g_free (priv);
-+ view->priv = NULL;
-+
-+ if (G_OBJECT_CLASS (parent_class)->finalize)
-+ (*G_OBJECT_CLASS (parent_class)->finalize) (object);
-+}
-+
-+
-+/* Unmap handler for the map view */
-+
-+static void
-+e_map_unmap (GtkWidget *widget)
-+{
-+ g_return_if_fail (widget != NULL);
-+ g_return_if_fail (IS_E_MAP (widget));
-+
-+ if (GTK_WIDGET_CLASS (parent_class)->unmap)
-+ (*GTK_WIDGET_CLASS (parent_class)->unmap) (widget);
-+}
-+
-+
-+/* Realize handler for the map view */
-+
-+static void
-+e_map_realize (GtkWidget *widget)
-+{
-+ GdkWindowAttr attr;
-+ int attr_mask;
-+
-+ g_return_if_fail (widget != NULL);
-+ g_return_if_fail (IS_E_MAP (widget));
-+
-+ GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
-+
-+ attr.window_type = GDK_WINDOW_CHILD;
-+ attr.x = widget->allocation.x;
-+ attr.y = widget->allocation.y;
-+ attr.width = widget->allocation.width;
-+ attr.height = widget->allocation.height;
-+ attr.wclass = GDK_INPUT_OUTPUT;
-+ attr.visual = gdk_rgb_get_visual ();
-+ attr.colormap = gdk_rgb_get_cmap ();
-+ attr.event_mask = gtk_widget_get_events (widget) |
-+ GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_KEY_PRESS_MASK |
-+ GDK_POINTER_MOTION_MASK;
-+
-+ attr_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
-+
-+ widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attr, attr_mask);
-+ gdk_window_set_user_data (widget->window, widget);
-+
-+ widget->style = gtk_style_attach (widget->style, widget->window);
-+
-+ gdk_window_set_back_pixmap (widget->window, NULL, FALSE);
-+ update_render_pixbuf (E_MAP (widget), GDK_INTERP_BILINEAR, TRUE);
-+}
-+
-+
-+/* Unrealize handler for the map view */
-+
-+static void
-+e_map_unrealize (GtkWidget *widget)
-+{
-+ g_return_if_fail (widget != NULL);
-+ g_return_if_fail (IS_E_MAP (widget));
-+
-+ if (GTK_WIDGET_CLASS (parent_class)->unrealize)
-+ (*GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
-+}
-+
-+
-+/* Size_request handler for the map view */
-+
-+static void
-+e_map_size_request (GtkWidget *widget, GtkRequisition *requisition)
-+{
-+ EMap *view;
-+ EMapPrivate *priv;
-+
-+ g_return_if_fail (widget != NULL);
-+ g_return_if_fail (IS_E_MAP (widget));
-+ g_return_if_fail (requisition != NULL);
-+
-+ view = E_MAP (widget);
-+ priv = view->priv;
-+
-+ /* TODO: Put real sizes here. */
-+
-+ requisition->width = gdk_pixbuf_get_width (priv->map_pixbuf);
-+ requisition->height = gdk_pixbuf_get_height (priv->map_pixbuf);
-+}
-+
-+
-+/* Size_allocate handler for the map view */
-+
-+static void
-+e_map_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
-+{
-+ EMap *view;
-+ EMapPrivate *priv;
-+ int xofs, yofs;
-+ GdkRectangle area;
-+
-+ g_return_if_fail (widget != NULL);
-+ g_return_if_fail (IS_E_MAP (widget));
-+ g_return_if_fail (allocation != NULL);
-+
-+ view = E_MAP (widget);
-+ priv = view->priv;
-+
-+ xofs = priv->xofs;
-+ yofs = priv->yofs;
-+
-+ /* Resize the window */
-+
-+ widget->allocation = *allocation;
-+
-+ if (GTK_WIDGET_REALIZED (widget))
-+ {
-+ gdk_window_move_resize (widget->window, allocation->x, allocation->y, allocation->width, allocation->height);
-+
-+ area.x = 0;
-+ area.y = 0;
-+ area.width = allocation->width;
-+ area.height = allocation->height;
-+ request_paint_area (E_MAP (widget), &area);
-+ }
-+
-+ update_render_pixbuf (view, GDK_INTERP_BILINEAR, TRUE);
-+}
-+
-+
-+/* Button press handler for the map view */
-+
-+static gint
-+e_map_button_press (GtkWidget *widget, GdkEventButton *event)
-+{
-+ EMap *view;
-+ EMapPrivate *priv;
-+
-+ view = E_MAP (widget);
-+ priv = view->priv;
-+
-+ if (!GTK_WIDGET_HAS_FOCUS (widget)) gtk_widget_grab_focus (widget);
-+ return TRUE;
-+}
-+
-+
-+/* Button release handler for the map view */
-+
-+static gint
-+e_map_button_release (GtkWidget *widget, GdkEventButton *event)
-+{
-+ EMap *view;
-+ EMapPrivate *priv;
-+
-+ view = E_MAP (widget);
-+ priv = view->priv;
-+
-+ if (event->button != 1) return FALSE;
-+
-+ gdk_pointer_ungrab (event->time);
-+ return TRUE;
-+}
-+
-+
-+/* Motion handler for the map view */
-+
-+static gint
-+e_map_motion (GtkWidget *widget, GdkEventMotion *event)
-+{
-+ EMap *view;
-+ EMapPrivate *priv;
-+
-+ view = E_MAP (widget);
-+ priv = view->priv;
-+
-+ return FALSE;
-+
-+/*
-+ * if (event->is_hint)
-+ * gdk_window_get_pointer(widget->window, &x, &y, &mods);
-+ * else
-+ * {
-+ * x = event->x;
-+ * y = event->y;
-+ * }
-+ *
-+ * return TRUE;
-+ */
-+}
-+
-+
-+/* Expose handler for the map view */
-+
-+static gint
-+e_map_expose (GtkWidget *widget, GdkEventExpose *event)
-+{
-+ EMap *view;
-+
-+ g_return_val_if_fail (widget != NULL, FALSE);
-+ g_return_val_if_fail (IS_E_MAP (widget), FALSE);
-+ g_return_val_if_fail (event != NULL, FALSE);
-+
-+ view = E_MAP (widget);
-+
-+ request_paint_area (view, &event->area);
-+ return TRUE;
-+}
-+
-+
-+/* Set_scroll_adjustments handler for the map view */
-+
-+static void
-+e_map_set_scroll_adjustments (GtkWidget *widget, GtkAdjustment *hadj, GtkAdjustment *vadj)
-+{
-+ EMap *view;
-+ EMapPrivate *priv;
-+ gboolean need_adjust;
-+
-+ g_return_if_fail (widget != NULL);
-+ g_return_if_fail (IS_E_MAP (widget));
-+
-+ view = E_MAP (widget);
-+ priv = view->priv;
-+
-+ if (hadj) g_return_if_fail (GTK_IS_ADJUSTMENT (hadj));
-+ else hadj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
-+
-+ if (vadj) g_return_if_fail (GTK_IS_ADJUSTMENT (vadj));
-+ else vadj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
-+
-+ if (priv->hadj && priv->hadj != hadj)
-+ {
-+ g_signal_handlers_disconnect_by_func (priv->hadj,
-+ adjustment_changed_cb,
-+ view);
-+ g_object_unref (priv->hadj);
-+ }
-+
-+ if (priv->vadj && priv->vadj != vadj)
-+ {
-+ g_signal_handlers_disconnect_by_func (priv->vadj,
-+ adjustment_changed_cb,
-+ view);
-+ g_object_unref (priv->vadj);
-+ }
-+
-+ need_adjust = FALSE;
-+
-+ if (priv->hadj != hadj)
-+ {
-+ priv->hadj = hadj;
-+ g_object_ref (priv->hadj);
-+ gtk_object_sink (GTK_OBJECT (priv->hadj));
-+
-+ g_signal_connect (priv->hadj, "value_changed",
-+ G_CALLBACK (adjustment_changed_cb), view);
-+
-+ need_adjust = TRUE;
-+ }
-+
-+ if (priv->vadj != vadj)
-+ {
-+ priv->vadj = vadj;
-+ g_object_ref (priv->vadj);
-+ gtk_object_sink (GTK_OBJECT (priv->vadj));
-+
-+ g_signal_connect (priv->vadj, "value_changed",
-+ G_CALLBACK (adjustment_changed_cb), view);
-+
-+ need_adjust = TRUE;
-+ }
-+
-+ if (need_adjust) adjustment_changed_cb (NULL, view);
-+}
-+
-+
-+/* Key press handler for the map view */
-+
-+static gint
-+e_map_key_press (GtkWidget *widget, GdkEventKey *event)
-+{
-+ EMap *view;
-+ EMapPrivate *priv;
-+ gboolean do_scroll;
-+ int xofs, yofs;
-+
-+ view = E_MAP (widget);
-+ priv = view->priv;
-+
-+ do_scroll = FALSE;
-+ xofs = yofs = 0;
-+
-+ switch (event->keyval)
-+ {
-+ case GDK_Up:
-+ do_scroll = TRUE;
-+ xofs = 0;
-+ yofs = -SCROLL_STEP_SIZE;
-+ break;
-+
-+ case GDK_Down:
-+ do_scroll = TRUE;
-+ xofs = 0;
-+ yofs = SCROLL_STEP_SIZE;
-+ break;
-+
-+ case GDK_Left:
-+ do_scroll = TRUE;
-+ xofs = -SCROLL_STEP_SIZE;
-+ yofs = 0;
-+ break;
-+
-+ case GDK_Right:
-+ do_scroll = TRUE;
-+ xofs = SCROLL_STEP_SIZE;
-+ yofs = 0;
-+ break;
-+
-+ default:
-+ return FALSE;
-+ }
-+
-+ if (do_scroll)
-+ {
-+ int x, y;
-+
-+ x = CLAMP (priv->xofs + xofs, 0, priv->hadj->upper - priv->hadj->page_size);
-+ y = CLAMP (priv->yofs + yofs, 0, priv->vadj->upper - priv->vadj->page_size);
-+
-+ scroll_to (view, x, y);
-+
-+ gtk_signal_handler_block_by_data (GTK_OBJECT (priv->hadj), view);
-+ gtk_signal_handler_block_by_data (GTK_OBJECT (priv->vadj), view);
-+
-+ priv->hadj->value = x;
-+ priv->vadj->value = y;
-+
-+ gtk_signal_emit_by_name (GTK_OBJECT (priv->hadj), "value_changed");
-+ gtk_signal_emit_by_name (GTK_OBJECT (priv->vadj), "value_changed");
-+
-+ gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->hadj), view);
-+ gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->vadj), view);
-+ }
-+
-+ return TRUE;
-+}
-+
-+
-+/* ---------------- *
-+ * Widget interface *
-+ * ---------------- */
-+
-+
-+/**
-+ * e_map_new:
-+ * @void:
-+ *
-+ * Creates a new empty map widget.
-+ *
-+ * Return value: A newly-created map widget.
-+ **/
-+
-+EMap *
-+e_map_new ()
-+{
-+ GtkWidget *widget;
-+
-+ widget = GTK_WIDGET (gtk_type_new (TYPE_E_MAP));
-+ return (E_MAP (widget));
-+}
-+
-+
-+/* --- Coordinate translation --- */
-+
-+
-+/* These functions translate coordinates between longitude/latitude and
-+ * the image x/y offsets, using the equidistant cylindrical projection.
-+ *
-+ * Longitude E <-180, 180]
-+ * Latitude E <-90, 90] */
-+
-+void
-+e_map_window_to_world (EMap *map, double win_x, double win_y, double *world_longitude, double *world_latitude)
-+{
-+ EMapPrivate *priv;
-+ int width, height;
-+
-+ g_return_if_fail (map);
-+
-+ priv = map->priv;
-+ g_return_if_fail (GTK_WIDGET_REALIZED (GTK_WIDGET (map)));
-+
-+ width = gdk_pixbuf_get_width (priv->map_render_pixbuf);
-+ height = gdk_pixbuf_get_height (priv->map_render_pixbuf);
-+
-+ *world_longitude = (win_x + priv->xofs - (double) width / 2.0) /
-+ ((double) width / 2.0) * 180.0;
-+ *world_latitude = ((double) height / 2.0 - win_y - priv->yofs) /
-+ ((double) height / 2.0) * 90.0;
-+}
-+
-+
-+void
-+e_map_world_to_window (EMap *map, double world_longitude, double world_latitude, double *win_x, double *win_y)
-+{
-+ EMapPrivate *priv;
-+ int width, height;
-+
-+ g_return_if_fail (map);
-+
-+ priv = map->priv;
-+ g_return_if_fail (priv->map_render_pixbuf);
-+ g_return_if_fail (world_longitude >= -180.0 && world_longitude <= 180.0);
-+ g_return_if_fail (world_latitude >= -90.0 && world_latitude <= 90.0);
-+
-+ width = gdk_pixbuf_get_width (priv->map_render_pixbuf);
-+ height = gdk_pixbuf_get_height (priv->map_render_pixbuf);
-+
-+ *win_x = (width / 2.0 + (width / 2.0) * world_longitude / 180.0) - priv->xofs;
-+ *win_y = (height / 2.0 - (height / 2.0) * world_latitude / 90.0) - priv->yofs;
-+
-+#ifdef DEBUG
-+ printf ("Map size: (%d, %d)\nCoords: (%.1f, %.1f) -> (%.1f, %.1f)\n---\n", width, height, world_longitude, world_latitude, *win_x, *win_y);
-+#endif
-+}
-+
-+
-+/* --- Zoom --- */
-+
-+
-+double
-+e_map_get_magnification (EMap *map)
-+{
-+ EMapPrivate *priv;
-+
-+ priv = map->priv;
-+ if (priv->zoom_state == E_MAP_ZOOMED_IN) return 2.0;
-+ else return 1.0;
-+}
-+
-+
-+void
-+e_map_zoom_to_location (EMap *map, double longitude, double latitude)
-+{
-+ EMapPrivate *priv;
-+ int width, height;
-+
-+ g_return_if_fail (map);
-+ g_return_if_fail (GTK_WIDGET_REALIZED (GTK_WIDGET (map)));
-+
-+ priv = map->priv;
-+
-+ if (priv->zoom_state == E_MAP_ZOOMED_IN) e_map_zoom_out (map);
-+ else if (priv->zoom_state != E_MAP_ZOOMED_OUT) return;
-+
-+ width = gdk_pixbuf_get_width (priv->map_render_pixbuf);
-+ height = gdk_pixbuf_get_height (priv->map_render_pixbuf);
-+
-+ priv->zoom_state = E_MAP_ZOOMING_IN;
-+ priv->zoom_target_long = longitude;
-+ priv->zoom_target_lat = latitude;
-+
-+ zoom_do (map);
-+}
-+
-+
-+void
-+e_map_zoom_out (EMap *map)
-+{
-+ EMapPrivate *priv;
-+ int width, height;
-+
-+ g_return_if_fail (map);
-+ g_return_if_fail (GTK_WIDGET_REALIZED (GTK_WIDGET (map)));
-+
-+ priv = map->priv;
-+
-+ if (priv->zoom_state != E_MAP_ZOOMED_IN) return;
-+
-+ width = gdk_pixbuf_get_width (priv->map_render_pixbuf);
-+ height = gdk_pixbuf_get_height (priv->map_render_pixbuf);
-+
-+ priv->zoom_state = E_MAP_ZOOMING_OUT;
-+ zoom_do (map);
-+ priv->zoom_state = E_MAP_ZOOMED_OUT;
-+}
-+
-+
-+void
-+e_map_set_smooth_zoom (EMap *map, gboolean state)
-+{
-+ ((EMapPrivate *) map->priv)->smooth_zoom = state;
-+}
-+
-+
-+gboolean
-+e_map_get_smooth_zoom (EMap *map)
-+{
-+ return (((EMapPrivate *) map->priv)->smooth_zoom);
-+}
-+
-+
-+void
-+e_map_freeze (EMap *map)
-+{
-+ ((EMapPrivate *) map->priv)->frozen = TRUE;
-+}
-+
-+
-+void
-+e_map_thaw (EMap *map)
-+{
-+ ((EMapPrivate *) map->priv)->frozen = FALSE;
-+ update_and_paint (map);
-+}
-+
-+
-+/* --- Point manipulation --- */
-+
-+
-+EMapPoint *
-+e_map_add_point (EMap *map, gchar *name, double longitude, double latitude, guint32 color_rgba)
-+{
-+ EMapPrivate *priv;
-+ EMapPoint *point;
-+
-+ priv = map->priv;
-+ point = g_new0 (EMapPoint, 1);
-+
-+ point->name = name; /* Can be NULL */
-+ point->longitude = longitude;
-+ point->latitude = latitude;
-+ point->rgba = color_rgba;
-+
-+ g_ptr_array_add (priv->points, (gpointer) point);
-+
-+ if (!priv->frozen)
-+ {
-+ update_render_point (map, point);
-+ repaint_point (map, point);
-+ }
-+
-+ return point;
-+}
-+
-+
-+void
-+e_map_remove_point (EMap *map, EMapPoint *point)
-+{
-+ EMapPrivate *priv;
-+
-+ priv = map->priv;
-+ g_ptr_array_remove (priv->points, point);
-+
-+ if (!((EMapPrivate *) map->priv)->frozen)
-+ {
-+ /* FIXME: Re-scaling the whole pixbuf is more than a little
-+ * overkill when just one point is removed */
-+
-+ update_render_pixbuf (map, GDK_INTERP_BILINEAR, TRUE);
-+ repaint_point (map, point);
-+ }
-+
-+ g_free (point);
-+}
-+
-+
-+void
-+e_map_point_get_location (EMapPoint *point, double *longitude, double *latitude)
-+{
-+ *longitude = point->longitude;
-+ *latitude = point->latitude;
-+}
-+
-+
-+gchar *
-+e_map_point_get_name (EMapPoint *point)
-+{
-+ return point->name;
-+}
-+
-+
-+guint32
-+e_map_point_get_color_rgba (EMapPoint *point)
-+{
-+ return point->rgba;
-+}
-+
-+
-+void
-+e_map_point_set_color_rgba (EMap *map, EMapPoint *point, guint32 color_rgba)
-+{
-+ point->rgba = color_rgba;
-+
-+ if (!((EMapPrivate *) map->priv)->frozen)
-+ {
-+ /* TODO: Redraw area around point only */
-+
-+ update_render_point (map, point);
-+ repaint_point (map, point);
-+ }
-+}
-+
-+
-+void
-+e_map_point_set_data (EMapPoint *point, gpointer data)
-+{
-+ point->user_data = data;
-+}
-+
-+
-+gpointer
-+e_map_point_get_data (EMapPoint *point)
-+{
-+ return point->user_data;
-+}
-+
-+
-+gboolean
-+e_map_point_is_in_view (EMap *map, EMapPoint *point)
-+{
-+ EMapPrivate *priv;
-+ double x, y;
-+
-+ priv = map->priv;
-+ if (!priv->map_render_pixbuf) return FALSE;
-+
-+ e_map_world_to_window (map, point->longitude, point->latitude, &x, &y);
-+
-+ if (x >= 0 && x < GTK_WIDGET (map)->allocation.width &&
-+ y >= 0 && y < GTK_WIDGET (map)->allocation.height)
-+ return TRUE;
-+
-+ return FALSE;
-+}
-+
-+
-+EMapPoint *
-+e_map_get_closest_point (EMap *map, double longitude, double latitude, gboolean in_view)
-+{
-+ EMapPrivate *priv;
-+ EMapPoint *point_chosen = NULL, *point;
-+ double min_dist = 0.0, dist;
-+ double dx, dy;
-+ int i;
-+
-+ priv = map->priv;
-+
-+ for (i = 0; i < priv->points->len; i++)
-+ {
-+ point = g_ptr_array_index (priv->points, i);
-+ if (in_view && !e_map_point_is_in_view (map, point)) continue;
-+
-+ dx = point->longitude - longitude;
-+ dy = point->latitude - latitude;
-+ dist = dx * dx + dy * dy;
-+
-+ if (!point_chosen || dist < min_dist)
-+ {
-+ min_dist = dist;
-+ point_chosen = point;
-+ }
-+ }
-+
-+ return point_chosen;
-+}
-+
-+
-+/* ------------------ *
-+ * Internal functions *
-+ * ------------------ */
-+
-+
-+static void
-+repaint_visible (EMap *map)
-+{
-+ GdkRectangle area;
-+
-+ area.x = 0;
-+ area.y = 0;
-+ area.width = GTK_WIDGET (map)->allocation.width;
-+ area.height = GTK_WIDGET (map)->allocation.height;
-+
-+ request_paint_area (map, &area);
-+}
-+
-+
-+static void
-+update_and_paint (EMap *map)
-+{
-+ update_render_pixbuf (map, GDK_INTERP_BILINEAR, TRUE);
-+ repaint_visible (map);
-+}
-+
-+
-+static gint
-+load_map_background (EMap *view, gchar *name)
-+{
-+ EMapPrivate *priv;
-+ GdkPixbuf *pb0;
-+
-+ priv = view->priv;
-+
-+ pb0 = gdk_pixbuf_new_from_file (name, NULL);
-+ if (!pb0)
-+ return FALSE;
-+
-+ if (priv->map_pixbuf) g_object_unref (priv->map_pixbuf);
-+ priv->map_pixbuf = pb0;
-+ update_render_pixbuf (view, GDK_INTERP_BILINEAR, TRUE);
-+
-+ return TRUE;
-+}
-+
-+
-+static void
-+update_render_pixbuf (EMap *map, ArtFilterLevel interp, gboolean render_overlays)
-+{
-+ EMapPrivate *priv;
-+ EMapPoint *point;
-+ int width, height, orig_width, orig_height;
-+ double zoom;
-+ int i;
-+
-+ if (!GTK_WIDGET_REALIZED (GTK_WIDGET (map))) return;
-+
-+ /* Set up value shortcuts */
-+
-+ priv = map->priv;
-+ width = GTK_WIDGET (map)->allocation.width;
-+ height = GTK_WIDGET (map)->allocation.height;
-+ orig_width = gdk_pixbuf_get_width (priv->map_pixbuf);
-+ orig_height = gdk_pixbuf_get_height (priv->map_pixbuf);
-+
-+ /* Compute scaled width and height based on the extreme dimension */
-+
-+ if ((double) width / orig_width > (double) height / orig_height)
-+ {
-+ zoom = (double) width / (double) orig_width;
-+ }
-+ else
-+ {
-+ zoom = (double) height / (double) orig_height;
-+ }
-+
-+ if (priv->zoom_state == E_MAP_ZOOMED_IN) zoom *= 2.0;
-+ height = (orig_height * zoom) + 0.5;
-+ width = (orig_width * zoom) + 0.5;
-+
-+ /* Reallocate the pixbuf */
-+
-+ if (priv->map_render_pixbuf) g_object_unref (priv->map_render_pixbuf);
-+ priv->map_render_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, /* No alpha */
-+ 8, width, height);
-+
-+ /* Scale the original map into the rendering pixbuf */
-+
-+ if (width > 1 && height > 1)
-+ {
-+ gdk_pixbuf_scale (priv->map_pixbuf, priv->map_render_pixbuf, 0, 0, /* Dest (x, y) */
-+ width, height, 0, 0, /* Offset (x, y) */
-+ zoom, zoom, /* Scale (x, y) */
-+ interp);
-+ }
-+
-+ if (render_overlays)
-+ {
-+ /* Add points */
-+
-+ for (i = 0; i < priv->points->len; i++)
-+ {
-+ point = g_ptr_array_index (priv->points, i);
-+ update_render_point (map, point);
-+ }
-+ }
-+
-+ /* Compute image offsets with respect to window */
-+
-+ set_scroll_area (map);
-+}
-+
-+
-+/* Queues a repaint of the specified area in window coordinates */
-+
-+static void
-+request_paint_area (EMap *view, GdkRectangle *area)
-+{
-+ EMapPrivate *priv;
-+ int width, height;
-+
-+ if (!GTK_WIDGET_DRAWABLE (GTK_WIDGET (view)) ||
-+ !GTK_WIDGET_REALIZED (GTK_WIDGET (view))) return;
-+
-+ priv = view->priv;
-+ if (!priv->map_render_pixbuf) return;
-+
-+ width = MIN (area->width, E_MAP_GET_WIDTH (view));
-+ height = MIN (area->height, E_MAP_GET_HEIGHT (view));
-+
-+ /* This satisfies paranoia. To be removed */
-+
-+ if (priv->xofs + width > gdk_pixbuf_get_width (priv->map_render_pixbuf))
-+ width = gdk_pixbuf_get_width (priv->map_render_pixbuf) - priv->xofs;
-+
-+ if (priv->yofs + height > gdk_pixbuf_get_height (priv->map_render_pixbuf))
-+ height = gdk_pixbuf_get_height (priv->map_render_pixbuf) - priv->yofs;
-+
-+ /* We rely on the fast case always being the case, since we load and
-+ * preprocess the source pixbuf ourselves */
-+
-+ if (gdk_pixbuf_get_colorspace (priv->map_render_pixbuf) == GDK_COLORSPACE_RGB && !gdk_pixbuf_get_has_alpha (priv->map_render_pixbuf) &&
-+ gdk_pixbuf_get_bits_per_sample (priv->map_render_pixbuf) == 8)
-+ {
-+ guchar *pixels;
-+ int rowstride;
-+
-+ rowstride = gdk_pixbuf_get_rowstride (priv->map_render_pixbuf);
-+ pixels = gdk_pixbuf_get_pixels (priv->map_render_pixbuf) + (area->y + priv->yofs) * rowstride + 3 * (area->x + priv->xofs);
-+ gdk_draw_rgb_image_dithalign (GTK_WIDGET (view)->window, GTK_WIDGET (view)->style->black_gc, area->x, area->y, width, height, GDK_RGB_DITHER_NORMAL, pixels, rowstride, 0, 0);
-+ return;
-+ }
-+
-+#ifdef DEBUG
-+ g_print ("Doing hard redraw.\n");
-+#endif
-+}
-+
-+static void
-+put_pixel_with_clipping (GdkPixbuf *pixbuf, gint x, gint y, guint rgba)
-+{
-+ gint width, height;
-+ gint rowstride, n_channels;
-+ guchar *pixels, *pixel;
-+
-+ width = gdk_pixbuf_get_width (pixbuf);
-+ height = gdk_pixbuf_get_height (pixbuf);
-+ rowstride = gdk_pixbuf_get_rowstride (pixbuf);
-+ n_channels = gdk_pixbuf_get_n_channels (pixbuf);
-+ pixels = gdk_pixbuf_get_pixels (pixbuf);
-+
-+ if (x < 0 || x >= width || y < 0 || y >= height)
-+ return;
-+
-+ pixel = pixels + (y * rowstride) + (x * n_channels);
-+
-+ *pixel = (rgba >> 24);
-+ *(pixel + 1) = (rgba >> 16) & 0x000000ff;
-+ *(pixel + 2) = (rgba >> 8) & 0x000000ff;
-+
-+ if (n_channels > 3)
-+ {
-+ *(pixel + 3) = rgba & 0x000000ff;
-+ }
-+}
-+
-+
-+/* Redraw point in client pixbuf */
-+
-+static void
-+update_render_point (EMap *map, EMapPoint *point)
-+{
-+ EMapPrivate *priv;
-+ GdkPixbuf *pb;
-+ int width, height;
-+ double px, py;
-+
-+ priv = map->priv;
-+ pb = priv->map_render_pixbuf;
-+ if (!pb) return;
-+
-+ width = gdk_pixbuf_get_width (pb);
-+ height = gdk_pixbuf_get_height (pb);
-+
-+ e_map_world_to_window (map, point->longitude, point->latitude, &px, &py);
-+ px += priv->xofs;
-+ py += priv->yofs;
-+
-+ put_pixel_with_clipping (pb, px, py, point->rgba);
-+ put_pixel_with_clipping (pb, px - 1, py, point->rgba);
-+ put_pixel_with_clipping (pb, px + 1, py, point->rgba);
-+ put_pixel_with_clipping (pb, px, py - 1, point->rgba);
-+ put_pixel_with_clipping (pb, px, py + 1, point->rgba);
-+
-+ put_pixel_with_clipping (pb, px - 2, py, 0x000000ff);
-+ put_pixel_with_clipping (pb, px + 2, py, 0x000000ff);
-+ put_pixel_with_clipping (pb, px, py - 2, 0x000000ff);
-+ put_pixel_with_clipping (pb, px, py + 2, 0x000000ff);
-+ put_pixel_with_clipping (pb, px - 1, py - 1, 0x000000ff);
-+ put_pixel_with_clipping (pb, px - 1, py + 1, 0x000000ff);
-+ put_pixel_with_clipping (pb, px + 1, py - 1, 0x000000ff);
-+ put_pixel_with_clipping (pb, px + 1, py + 1, 0x000000ff);
-+}
-+
-+
-+/* Repaint point on X server */
-+
-+static void
-+repaint_point (EMap *map, EMapPoint *point)
-+{
-+ EMapPrivate *priv;
-+ GdkRectangle area;
-+ double px, py;
-+
-+ if (!e_map_point_is_in_view (map, point)) return;
-+ priv = map->priv;
-+
-+ e_map_world_to_window (map, point->longitude, point->latitude, &px, &py);
-+
-+ area.x = (int) px - 2;
-+ area.y = (int) py - 2;
-+ area.width = 5;
-+ area.height = 5;
-+ request_paint_area (map, &area);
-+}
-+
-+
-+static void
-+center_at (EMap *map, int x, int y, gboolean scroll)
-+{
-+ EMapPrivate *priv;
-+ int pb_width, pb_height,
-+ view_width, view_height;
-+
-+ priv = map->priv;
-+
-+ pb_width = E_MAP_GET_WIDTH (map);
-+ pb_height = E_MAP_GET_HEIGHT (map);
-+
-+ view_width = GTK_WIDGET (map)->allocation.width;
-+ view_height = GTK_WIDGET (map)->allocation.height;
-+
-+ x = CLAMP (x - (view_width / 2), 0, pb_width - view_width);
-+ y = CLAMP (y - (view_height / 2), 0, pb_height - view_height);
-+
-+ if (scroll) scroll_to (map, x, y);
-+ else
-+ {
-+ priv->xofs = x;
-+ priv->yofs = y;
-+ }
-+}
-+
-+
-+static void
-+smooth_center_at (EMap *map, int x, int y)
-+{
-+ EMapPrivate *priv;
-+ int pb_width, pb_height,
-+ view_width, view_height;
-+ int dx, dy;
-+
-+ priv = map->priv;
-+
-+ pb_width = E_MAP_GET_WIDTH (map);
-+ pb_height = E_MAP_GET_HEIGHT (map);
-+
-+ view_width = GTK_WIDGET (map)->allocation.width;
-+ view_height = GTK_WIDGET (map)->allocation.height;
-+
-+ x = CLAMP (x - (view_width / 2), 0, pb_width - view_width);
-+ y = CLAMP (y - (view_height / 2), 0, pb_height - view_height);
-+
-+ for (;;)
-+ {
-+ if (priv->xofs == x && priv->yofs == y) break;
-+
-+ dx = (x < priv->xofs) ? -1 : (x > priv->xofs) ? 1 : 0;
-+ dy = (y < priv->yofs) ? -1 : (y > priv->yofs) ? 1 : 0;
-+
-+ scroll_to (map, priv->xofs + dx, priv->yofs + dy);
-+ }
-+}
-+
-+
-+/* Scrolls the view to the specified offsets. Does not perform range checking! */
-+
-+static void
-+scroll_to (EMap *view, int x, int y)
-+{
-+ EMapPrivate *priv;
-+ int xofs, yofs;
-+ GdkWindow *window;
-+ GdkGC *gc;
-+ int width, height;
-+ int src_x, src_y;
-+ int dest_x, dest_y;
-+ GdkEvent *event;
-+
-+ priv = view->priv;
-+
-+ /* Compute offsets and check bounds */
-+
-+ xofs = x - priv->xofs;
-+ yofs = y - priv->yofs;
-+
-+ if (xofs == 0 && yofs == 0) return;
-+
-+ priv->xofs = x;
-+ priv->yofs = y;
-+
-+ if (!GTK_WIDGET_DRAWABLE (view)) return;
-+
-+ width = GTK_WIDGET (view)->allocation.width;
-+ height = GTK_WIDGET (view)->allocation.height;
-+
-+ if (abs (xofs) >= width || abs (yofs) >= height)
-+ {
-+ GdkRectangle area;
-+
-+ area.x = 0;
-+ area.y = 0;
-+ area.width = width;
-+ area.height = height;
-+
-+ request_paint_area (view, &area);
-+ return;
-+ }
-+
-+ window = GTK_WIDGET (view)->window;
-+
-+ /* Copy the window area */
-+
-+ src_x = xofs < 0 ? 0 : xofs;
-+ src_y = yofs < 0 ? 0 : yofs;
-+ dest_x = xofs < 0 ? -xofs : 0;
-+ dest_y = yofs < 0 ? -yofs : 0;
-+
-+ gc = gdk_gc_new (window);
-+ gdk_gc_set_exposures (gc, TRUE);
-+
-+ gdk_window_copy_area (window, gc, dest_x, dest_y, window, src_x, src_y, width - abs (xofs), height - abs (yofs));
-+
-+ gdk_gc_destroy (gc);
-+
-+ /* Add the scrolled-in region */
-+
-+ if (xofs)
-+ {
-+ GdkRectangle r;
-+
-+ r.x = xofs < 0 ? 0 : width - xofs;
-+ r.y = 0;
-+ r.width = abs (xofs);
-+ r.height = height;
-+
-+ request_paint_area (view, &r);
-+ }
-+
-+ if (yofs)
-+ {
-+ GdkRectangle r;
-+
-+ r.x = 0;
-+ r.y = yofs < 0 ? 0 : height - yofs;
-+ r.width = width;
-+ r.height = abs (yofs);
-+
-+ request_paint_area (view, &r);
-+ }
-+
-+ /* Process graphics exposures */
-+
-+ while ((event = gdk_event_get_graphics_expose (window)) != NULL)
-+ {
-+ gtk_widget_event (GTK_WIDGET (view), event);
-+
-+ if (event->expose.count == 0)
-+ {
-+ gdk_event_free (event);
-+ break;
-+ }
-+
-+ gdk_event_free (event);
-+ }
-+}
-+
-+
-+static int divide_seq[] =
-+{
-+ /* Dividends for divisor of 2 */
-+
-+ -2,
-+
-+ 1,
-+
-+ /* Dividends for divisor of 4 */
-+
-+ -4,
-+
-+ 1, 3,
-+
-+ /* Dividends for divisor of 8 */
-+
-+ -8,
-+
-+ 1, 5, 3, 7,
-+
-+ /* Dividends for divisor of 16 */
-+
-+ -16,
-+
-+ 1, 9, 5, 13, 3, 11, 7, 15,
-+
-+ /* Dividends for divisor of 32 */
-+
-+ -32,
-+
-+ 1, 17, 9, 25, 5, 21, 13, 29, 3, 19,
-+ 11, 27, 7, 23, 15, 31,
-+
-+ /* Dividends for divisor of 64 */
-+
-+ -64,
-+
-+ 1, 33, 17, 49, 9, 41, 25, 57, 5, 37,
-+ 21, 53, 13, 45, 29, 61, 3, 35, 19, 51,
-+ 11, 43, 27, 59, 7, 39, 23, 55, 15, 47,
-+ 31, 63,
-+
-+ /* Dividends for divisor of 128 */
-+
-+ -128,
-+
-+ 1, 65, 33, 97, 17, 81, 49, 113, 9, 73,
-+ 41, 105, 25, 89, 57, 121, 5, 69, 37, 101,
-+ 21, 85, 53, 117, 13, 77, 45, 109, 29, 93,
-+ 61, 125, 3, 67, 35, 99, 19, 83, 51, 115,
-+ 11, 75, 43, 107, 27, 91, 59, 123, 7, 71,
-+ 39, 103, 23, 87, 55, 119, 15, 79, 47, 111,
-+ 31, 95, 63, 127,
-+
-+ /* Dividends for divisor of 256 */
-+
-+ -256,
-+
-+ 1, 129, 65, 193, 33, 161, 97, 225, 17, 145,
-+ 81, 209, 49, 177, 113, 241, 9, 137, 73, 201,
-+ 41, 169, 105, 233, 25, 153, 89, 217, 57, 185,
-+ 121, 249, 5, 133, 69, 197, 37, 165, 101, 229,
-+ 21, 149, 85, 213, 53, 181, 117, 245, 13, 141,
-+ 77, 205, 45, 173, 109, 237, 29, 157, 93, 221,
-+ 61, 189, 125, 253, 3, 131, 67, 195, 35, 163,
-+ 99, 227, 19, 147, 83, 211, 51, 179, 115, 243,
-+ 11, 139, 75, 203, 43, 171, 107, 235, 27, 155,
-+ 91, 219, 59, 187, 123, 251, 7, 135, 71, 199,
-+ 39, 167, 103, 231, 23, 151, 87, 215, 55, 183,
-+ 119, 247, 15, 143, 79, 207, 47, 175, 111, 239,
-+ 31, 159, 95, 223, 63, 191, 127, 255,
-+
-+ 0
-+};
-+
-+
-+typedef enum
-+{
-+ AXIS_X,
-+ AXIS_Y
-+}
-+AxisType;
-+
-+
-+static void
-+blowup_window_area (GdkWindow *window, gint area_x, gint area_y, gint target_x, gint target_y, gint total_width, gint total_height, gfloat zoom_factor)
-+{
-+ GdkGC *gc;
-+ AxisType strong_axis;
-+ gfloat axis_factor, axis_counter;
-+ gint zoom_chunk;
-+ gint divisor_width = 0, divisor_height = 0;
-+ gint divide_width_index, divide_height_index;
-+ gint area_width, area_height;
-+ gint i, j;
-+ int line;
-+
-+
-+ /* Set up the GC we'll be using */
-+
-+ gc = gdk_gc_new (window);
-+ gdk_gc_set_exposures (gc, FALSE);
-+
-+ /* Get area constraints */
-+
-+ gdk_window_get_size (window, &area_width, &area_height);
-+
-+ /* Initialize area division array indexes */
-+
-+ divide_width_index = divide_height_index = 0;
-+
-+ /* Initialize axis counter */
-+
-+ axis_counter = 0.0;
-+
-+ /* Find the strong axis (which is the basis for iteration) and the ratio
-+ * at which the other axis will be scaled.
-+ *
-+ * Also determine how many lines to expand in one fell swoop, and store
-+ * this figure in zoom_chunk. */
-+
-+ if (area_width > area_height)
-+ {
-+ strong_axis = AXIS_X;
-+ axis_factor = (double) area_height / (double) area_width;
-+ zoom_chunk = MAX (1, area_width / 250);
-+ i = (area_width * (zoom_factor - 1.0)) / zoom_chunk;
-+ }
-+ else
-+ {
-+ strong_axis = AXIS_Y;
-+ axis_factor = (double) area_width / (double) area_height;
-+ zoom_chunk = MAX (1, area_height / 250);
-+ i = (area_height * (zoom_factor - 1.0)) / zoom_chunk;
-+ }
-+
-+ /* Go, go, devil bunnies! Gogo devil bunnies! */
-+
-+ for (; i > 0; i--)
-+ {
-+ /* Reset division sequence table indexes as necessary */
-+
-+ if (!divide_seq[divide_width_index]) divide_width_index = 0;
-+ if (!divide_seq[divide_height_index]) divide_height_index = 0;
-+
-+ /* Set new divisor if found in table */
-+
-+ if (divide_seq[divide_width_index] < 0)
-+ divisor_width = abs (divide_seq[divide_width_index++]);
-+ if (divide_seq[divide_height_index] < 0)
-+ divisor_height = abs (divide_seq[divide_height_index++]);
-+
-+ /* Widen */
-+
-+ if (strong_axis == AXIS_X || axis_counter >= 1.0)
-+ {
-+ line = ((divide_seq[divide_width_index] * area_width) / divisor_width) + 0.5;
-+
-+ if ((line < target_x && target_x > area_width / 2) || (line > target_x && target_x > (area_width / 2) + zoom_chunk))
-+ {
-+ /* Push left */
-+
-+ for (j = 0; j < zoom_chunk - 1; j++)
-+ gdk_window_copy_area (window, gc, line + j + 1, 0, window, line, 0, 1, area_height);
-+
-+ gdk_window_copy_area (window, gc, 0, 0, window, zoom_chunk, 0, line, area_height);
-+ if (line > target_x) target_x -= zoom_chunk;
-+ }
-+ else
-+ {
-+ /* Push right */
-+
-+ for (j = 0; j < zoom_chunk - 1; j++)
-+ gdk_window_copy_area (window, gc, line + j - (zoom_chunk - 1), 0, window, line - zoom_chunk, 0, 1, area_height);
-+
-+ gdk_window_copy_area (window, gc, line, 0, window, line - zoom_chunk, 0, area_width - line, area_height);
-+ if (line < target_x) target_x += zoom_chunk;
-+ }
-+ }
-+
-+ if (strong_axis == AXIS_Y || axis_counter >= 1.0)
-+ {
-+ /* Heighten */
-+
-+ line = ((divide_seq[divide_height_index] * area_height) / divisor_height) + 0.5;
-+
-+ if ((line < target_y && target_y > area_height / 2) || (line > target_y && target_y > (area_height / 2) + zoom_chunk))
-+ {
-+ /* Push up */
-+
-+ for (j = 0; j < zoom_chunk - 1; j++)
-+ gdk_window_copy_area (window, gc, 0, line + j + 1, window, 0, line, area_width, 1);
-+
-+ gdk_window_copy_area (window, gc, 0, 0, window, 0, zoom_chunk, area_width, line);
-+ if (line > target_y) target_y -= zoom_chunk;
-+ }
-+ else
-+ {
-+ /* Push down */
-+
-+ for (j = 0; j < zoom_chunk - 1; j++)
-+ gdk_window_copy_area (window, gc, 0, line + j - (zoom_chunk - 1), window, 0, line - zoom_chunk, area_width, 1);
-+
-+ gdk_window_copy_area (window, gc, 0, line, window, 0, line - zoom_chunk, area_width, area_height - line);
-+ if (line < target_y) target_y += zoom_chunk;
-+ }
-+ }
-+
-+ divide_width_index++;
-+ divide_height_index++;
-+ if (axis_counter >= 1.0) axis_counter -= 1.0;
-+ axis_counter += axis_factor;
-+ }
-+
-+ /* Free our GC */
-+
-+ gdk_gc_destroy (gc);
-+}
-+
-+
-+static void
-+zoom_in_smooth (EMap *map)
-+{
-+ GdkRectangle area;
-+ EMapPrivate *priv;
-+ GdkWindow *window;
-+ int width, height;
-+ int win_width, win_height;
-+ int target_width, target_height;
-+ double x, y;
-+
-+ g_return_if_fail (map);
-+ g_return_if_fail (GTK_WIDGET_REALIZED (GTK_WIDGET (map)));
-+
-+ area.x = 0;
-+ area.y = 0;
-+ area.width = GTK_WIDGET (map)->allocation.width;
-+ area.height = GTK_WIDGET (map)->allocation.height;
-+
-+ priv = map->priv;
-+ window = GTK_WIDGET (map)->window;
-+ width = gdk_pixbuf_get_width (priv->map_render_pixbuf);
-+ height = gdk_pixbuf_get_height (priv->map_render_pixbuf);
-+ win_width = GTK_WIDGET (map)->allocation.width;
-+ win_height = GTK_WIDGET (map)->allocation.height;
-+ target_width = win_width / 4;
-+ target_height = win_height / 4;
-+
-+ /* Center the target point as much as possible */
-+
-+ e_map_world_to_window (map, priv->zoom_target_long, priv->zoom_target_lat, &x, &y);
-+ smooth_center_at (map, x + priv->xofs, y + priv->yofs);
-+
-+ /* Render and paint a temporary map without overlays, so they don't get in
-+ * the way (look ugly) while zooming */
-+
-+ update_render_pixbuf (map, GDK_INTERP_BILINEAR, FALSE);
-+ request_paint_area (map, &area);
-+
-+ /* Find out where in the area we're going to zoom to */
-+
-+ e_map_world_to_window (map, priv->zoom_target_long, priv->zoom_target_lat, &x, &y);
-+
-+ /* Pre-render the zoomed-in map, so we can put it there quickly when the
-+ * blowup sequence ends */
-+
-+ priv->zoom_state = E_MAP_ZOOMED_IN;
-+ update_render_pixbuf (map, GDK_INTERP_BILINEAR, TRUE);
-+
-+ /* Do the blowup */
-+
-+ blowup_window_area (window, priv->xofs, priv->yofs, x, y, width, height, 1.68);
-+
-+ /* Set new scroll offsets and paint the zoomed map */
-+
-+ e_map_world_to_window (map, priv->zoom_target_long, priv->zoom_target_lat, &x, &y);
-+ priv->xofs = CLAMP (priv->xofs + x - area.width / 2.0, 0, E_MAP_GET_WIDTH (map) - area.width);
-+ priv->yofs = CLAMP (priv->yofs + y - area.height / 2.0, 0, E_MAP_GET_HEIGHT (map) - area.height);
-+
-+ request_paint_area (map, &area);
-+}
-+
-+
-+static void
-+zoom_in (EMap *map)
-+{
-+ GdkRectangle area;
-+ EMapPrivate *priv;
-+ double x, y;
-+
-+ priv = map->priv;
-+
-+ area.x = 0;
-+ area.y = 0;
-+ area.width = GTK_WIDGET (map)->allocation.width;
-+ area.height = GTK_WIDGET (map)->allocation.height;
-+
-+ priv->zoom_state = E_MAP_ZOOMED_IN;
-+
-+ update_render_pixbuf (map, GDK_INTERP_BILINEAR, TRUE);
-+
-+ e_map_world_to_window (map, priv->zoom_target_long, priv->zoom_target_lat, &x, &y);
-+ priv->xofs = CLAMP (priv->xofs + x - area.width / 2.0, 0, E_MAP_GET_WIDTH (map) - area.width);
-+ priv->yofs = CLAMP (priv->yofs + y - area.height / 2.0, 0, E_MAP_GET_HEIGHT (map) - area.height);
-+
-+ request_paint_area (map, &area);
-+}
-+
-+
-+static void
-+zoom_out (EMap *map)
-+{
-+ GdkRectangle area;
-+ EMapPrivate *priv;
-+ double longitude, latitude;
-+ double x, y;
-+
-+ priv = map->priv;
-+
-+ area.x = 0;
-+ area.y = 0;
-+ area.width = GTK_WIDGET (map)->allocation.width;
-+ area.height = GTK_WIDGET (map)->allocation.height;
-+
-+ /* Must be done before update_render_pixbuf() */
-+
-+ e_map_window_to_world (map, area.width / 2, area.height / 2,
-+ &longitude, &latitude);
-+
-+ priv->zoom_state = E_MAP_ZOOMED_OUT;
-+ update_render_pixbuf (map, GDK_INTERP_BILINEAR, TRUE);
-+
-+ e_map_world_to_window (map, longitude, latitude, &x, &y);
-+ center_at (map, x + priv->xofs, y + priv->yofs, FALSE);
-+/* request_paint_area (map, &area); */
-+ repaint_visible (map);
-+}
-+
-+
-+static void
-+zoom_do (EMap *map)
-+{
-+ EMapPrivate *priv;
-+
-+ priv = map->priv;
-+
-+ gtk_signal_handler_block_by_data (GTK_OBJECT (priv->hadj), map);
-+ gtk_signal_handler_block_by_data (GTK_OBJECT (priv->vadj), map);
-+
-+ if (priv->zoom_state == E_MAP_ZOOMING_IN)
-+ {
-+ if (e_map_get_smooth_zoom (map)) zoom_in_smooth (map);
-+ else zoom_in (map);
-+ }
-+ else if (priv->zoom_state == E_MAP_ZOOMING_OUT)
-+ {
-+/* if (e_map_get_smooth_zoom(map)) zoom_out_smooth(map); */
-+ zoom_out (map);
-+ }
-+
-+ gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->hadj), map);
-+ gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->vadj), map);
-+
-+ set_scroll_area(map);
-+}
-+
-+
-+/* Callback used when an adjustment is changed */
-+
-+static void
-+adjustment_changed_cb (GtkAdjustment *adj, gpointer data)
-+{
-+ EMap *view;
-+ EMapPrivate *priv;
-+
-+ view = E_MAP (data);
-+ priv = view->priv;
-+
-+ scroll_to (view, priv->hadj->value, priv->vadj->value);
-+}
-+
-+
-+static void
-+set_scroll_area (EMap *view)
-+{
-+ EMapPrivate *priv;
-+
-+ priv = view->priv;
-+
-+ if (!GTK_WIDGET_REALIZED (GTK_WIDGET (view))) return;
-+ if (!priv->hadj || !priv->vadj) return;
-+
-+ /* Set scroll increments */
-+
-+ priv->hadj->page_size = GTK_WIDGET (view)->allocation.width;
-+ priv->hadj->page_increment = GTK_WIDGET (view)->allocation.width / 2;
-+ priv->hadj->step_increment = SCROLL_STEP_SIZE;
-+
-+ priv->vadj->page_size = GTK_WIDGET (view)->allocation.height;
-+ priv->vadj->page_increment = GTK_WIDGET (view)->allocation.height / 2;
-+ priv->vadj->step_increment = SCROLL_STEP_SIZE;
-+
-+ /* Set scroll bounds and new offsets */
-+
-+ priv->hadj->lower = 0;
-+ if (priv->map_render_pixbuf)
-+ priv->hadj->upper = gdk_pixbuf_get_width (priv->map_render_pixbuf);
-+
-+ priv->vadj->lower = 0;
-+ if (priv->map_render_pixbuf)
-+ priv->vadj->upper = gdk_pixbuf_get_height (priv->map_render_pixbuf);
-+
-+ gtk_signal_emit_by_name (GTK_OBJECT (priv->hadj), "changed");
-+ gtk_signal_emit_by_name (GTK_OBJECT (priv->vadj), "changed");
-+
-+ priv->xofs = CLAMP (priv->xofs, 0, priv->hadj->upper - priv->hadj->page_size);
-+ priv->yofs = CLAMP (priv->yofs, 0, priv->vadj->upper - priv->vadj->page_size);
-+
-+ if (priv->hadj->value != priv->xofs)
-+ {
-+ priv->hadj->value = priv->xofs;
-+
-+ gtk_signal_handler_block_by_data (GTK_OBJECT (priv->hadj), view);
-+ gtk_signal_emit_by_name (GTK_OBJECT (priv->hadj), "value_changed");
-+ gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->hadj), view);
-+ }
-+
-+ if (priv->vadj->value != priv->yofs)
-+ {
-+ priv->vadj->value = priv->yofs;
-+
-+ gtk_signal_handler_block_by_data (GTK_OBJECT (priv->vadj), view);
-+ gtk_signal_emit_by_name (GTK_OBJECT (priv->vadj), "value_changed");
-+ gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->vadj), view);
-+ }
-+}
-+
-diff -Nrup gnome-panel-2.14.1/applets/clock/e-map/e-map.h ../gnome-panel-2.14.1/applets/clock/e-map/e-map.h
---- gnome-panel-2.14.1/applets/clock/e-map/e-map.h 1970-01-01 01:00:00.000000000 +0100
-+++ ../gnome-panel-2.14.1/applets/clock/e-map/e-map.h 2006-06-12 16:18:42.527305000 +0200
-@@ -0,0 +1,139 @@
-+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-+/* Map widget.
-+ *
-+ * Copyright (C) 2000-2001 Ximian, Inc.
-+ *
-+ * Authors: Hans Petter Jansson <[email protected]>
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of version 2 of the GNU General Public
-+ * License as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public
-+ * License along with this program; if not, write to the
-+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-+ * Boston, MA 02111-1307, USA.
-+ */
-+
-+#ifndef E_MAP_H
-+#define E_MAP_H
-+
-+#include <gtk/gtkwidget.h>
-+
-+#define TYPE_E_MAP (e_map_get_type ())
-+#define E_MAP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_E_MAP, EMap))
-+#define E_MAP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_E_MAP, EMapClass))
-+#define IS_E_MAP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_E_MAP))
-+#define IS_E_MAP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_E_MAP))
-+
-+typedef struct _EMap EMap;
-+typedef struct _EMapClass EMapClass;
-+typedef struct _EMapPoint EMapPoint;
-+
-+struct _EMap
-+{
-+ GtkWidget widget;
-+
-+ /* Private data */
-+ gpointer priv;
-+};
-+
-+struct _EMapClass
-+{
-+ GtkWidgetClass parent_class;
-+
-+ /* Notification signals */
-+ void (*zoom_fit) (EMap * view);
-+
-+ /* GTK+ scrolling interface */
-+ void (*set_scroll_adjustments) (GtkWidget * widget,
-+ GtkAdjustment * hadj,
-+ GtkAdjustment * vadj);
-+};
-+
-+/* The definition of Dot */
-+
-+struct _EMapPoint
-+{
-+ gchar *name; /* Can be NULL */
-+ double longitude, latitude;
-+ guint32 rgba;
-+ gpointer user_data;
-+};
-+
-+
-+/* --- Widget --- */
-+
-+GtkType e_map_get_type (void);
-+
-+EMap *e_map_new (void);
-+
-+/* Stop doing redraws when map data changes (e.g. by modifying points) */
-+void e_map_freeze (EMap *map);
-+
-+/* Do an immediate repaint, and start doing realtime repaints again */
-+void e_map_thaw (EMap *map);
-+
-+/* --- Coordinate translation --- */
-+
-+/* Translates window-relative coords to lat/long */
-+void e_map_window_to_world (EMap *map,
-+ double win_x, double win_y,
-+ double *world_longitude, double *world_latitude);
-+
-+/* Translates lat/long to window-relative coordinates. Note that the
-+ * returned coordinates can be negative or greater than the current size
-+ * of the allocation area */
-+void e_map_world_to_window (EMap *map,
-+ double world_longitude, double world_latitude,
-+ double *win_x, double *win_y);
-+
-+/* --- Zoom --- */
-+
-+double e_map_get_magnification (EMap *map);
-+
-+/* Pass TRUE if we want the smooth zoom hack */
-+void e_map_set_smooth_zoom (EMap *map, gboolean state);
-+
-+/* TRUE if smooth zoom hack will be employed */
-+gboolean e_map_get_smooth_zoom (EMap *map);
-+
-+/* NB: Function definition will change shortly */
-+void e_map_zoom_to_location (EMap *map, double longitude, double latitude);
-+
-+/* Zoom to mag factor 1.0 */
-+void e_map_zoom_out (EMap *map);
-+
-+/* --- Points --- */
-+
-+EMapPoint *e_map_add_point (EMap *map, gchar *name,
-+ double longitude, double latitude,
-+ guint32 color_rgba);
-+
-+void e_map_remove_point (EMap *map, EMapPoint *point);
-+
-+void e_map_point_get_location (EMapPoint *point,
-+ double *longitude, double *latitude);
-+
-+gchar *e_map_point_get_name (EMapPoint *point);
-+
-+guint32 e_map_point_get_color_rgba (EMapPoint *point);
-+
-+void e_map_point_set_color_rgba (EMap *map, EMapPoint *point, guint32 color_rgba);
-+
-+void e_map_point_set_data (EMapPoint *point, gpointer data);
-+
-+gpointer e_map_point_get_data (EMapPoint *point);
-+
-+gboolean e_map_point_is_in_view (EMap *map, EMapPoint *point);
-+
-+EMapPoint *e_map_get_closest_point (EMap *map, double longitude, double latitude,
-+ gboolean in_view);
-+
-+#endif
-+
-diff -Nrup gnome-panel-2.14.1/applets/clock/multi-timezone.c ../gnome-panel-2.14.1/applets/clock/multi-timezone.c
---- gnome-panel-2.14.1/applets/clock/multi-timezone.c 1970-01-01 01:00:00.000000000 +0100
-+++ ../gnome-panel-2.14.1/applets/clock/multi-timezone.c 2006-06-12 16:18:42.525310000 +0200
-@@ -0,0 +1,541 @@
-+#include <strings.h>
-+#include "config.h"
-+#include "clock.h"
-+
-+#define GW(name) glade_xml_get_widget (tsd->xml, name)
-+static const char* KEY_TIPS_ZONE = "tips-zone";
-+/* popup part */
-+static void set_tip_zone_to_gconf (TimezoneSelectionDialog *tsd, char *zone, char *nick, int key_num);
-+static void update_list_tip_zone (ClockData *cd);
-+
-+static void
-+hide_it (GtkWidget* w, GdkEventButton *event, ClockData *cd)
-+{
-+ gtk_widget_hide (cd->multizone_popup);
-+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cd->multizone_toggle),
-+ FALSE);
-+}
-+
-+static void
-+set_zone_tip_from_name (ClockData *cd, GtkWidget *widget, char *zone)
-+{
-+ TzInfo *tz;
-+ TzLocation *tz_loc = NULL;
-+
-+ if (!zone)
-+ return;
-+
-+ if (!cd->tzdb)
-+ {
-+ cd->tzdb = tz_load_db ();
-+ if (!cd->tzdb)
-+ return;
-+ }
-+
-+ tz_loc = tz_get_location_by_name (cd->tzdb, zone);
-+
-+ if (!tz_loc)
-+ {
-+ char *current_timezone = tz_get_system_timezone ();
-+ if (current_timezone)
-+ {
-+ tz_loc = tz_get_location_by_name (cd->tzdb,
-+ current_timezone);
-+ g_free (current_timezone);
-+ }
-+ }
-+ if (tz_loc)
-+ {
-+ char *tip;
-+ tz = tz_info_from_location (tz_loc);
-+
-+ tip = g_strdup_printf ("%s - %s (%s)\nGMT%s%ld %s%s%s",
-+ _(tz_loc->zone),
-+ tz_loc->country,
-+ tz->tzname_normal,
-+ (tz->utc_offset / 3600) >= 0 ? "+" : " ",
-+ tz->utc_offset / 3600,
-+ tz->daylight == 0 ? " ": _("use daylight savings"),
-+ tz_loc->comment ? "\n" : " ",
-+ tz_loc->comment ? tz_loc->comment : " ");
-+ clock_set_tooltip (cd->applet, widget, tip);
-+ g_free (tip);
-+ }
-+}
-+
-+static GtkWidget *
-+add_timezone_button (ClockData *cd,
-+ TipZone *tip)
-+{
-+ GtkWidget *hbox, *label_zone, *label_time, *event_box;
-+
-+ hbox = gtk_hbox_new (TRUE, 0);
-+ label_zone = gtk_label_new (tip->nick);
-+ label_time = gtk_label_new ("12:00");
-+ event_box = gtk_event_box_new ();
-+
-+
-+ tip->time_label = label_time;
-+ tip->nick_label = label_zone;
-+
-+
-+ gtk_box_pack_start (GTK_BOX (hbox), label_zone, TRUE, TRUE, 2);
-+ gtk_misc_set_alignment (GTK_MISC (label_zone), 0, 0.5);
-+ gtk_box_pack_start (GTK_BOX (hbox), label_time, TRUE, TRUE, 2);
-+ gtk_misc_set_alignment (GTK_MISC (label_time), 1, 0.5);
-+
-+ gtk_container_add (GTK_CONTAINER (event_box), hbox);
-+
-+ set_zone_tip_from_name (cd, event_box, tip->zone);
-+
-+ g_signal_connect (event_box,
-+ "button-press-event",
-+ G_CALLBACK (hide_it),
-+ cd);
-+
-+ gtk_widget_show_all (event_box);
-+ return event_box;
-+}
-+
-+static gboolean
-+close_on_escape (GtkWidget *widget,
-+ GdkEventKey *event,
-+ ClockData *cd)
-+{
-+ if (event->keyval == GDK_Escape) {
-+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cd->toggle), FALSE);
-+ return TRUE;
-+ }
-+
-+ return FALSE;
-+}
-+
-+static gboolean
-+delete_event (GtkWidget *widget,
-+ GdkEvent *event,
-+ ClockData *cd)
-+{
-+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cd->toggle), FALSE);
-+ return TRUE;
-+}
-+
-+static void
-+edit_zones (GtkWidget *w, ClockData *cd)
-+{
-+ if (cd->multizone_popup)
-+ {
-+ gtk_widget_hide (cd->multizone_popup);
-+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cd->multizone_toggle),
-+ FALSE);
-+ }
-+ if (cd->tsd)
-+ {
-+ gtk_window_set_screen (GTK_WINDOW (cd->timezone_dialog),
-+ gtk_widget_get_screen (cd->applet));
-+ gtk_window_present (GTK_WINDOW (cd->timezone_dialog));
-+ return;
-+ }
-+
-+ display_timezone_selection_dialog (NULL, cd, NULL);
-+}
-+
-+GtkWidget *
-+create_multi_timezones_popup (ClockData *cd,
-+ GdkScreen *screen)
-+{
-+ GtkWindow *window;
-+ GtkWidget *vbox_zones, *vbox, *separ, *button, *frame;
-+ GSList *tmp_list;
-+
-+ update_list_tip_zone (cd);
-+
-+ window = GTK_WINDOW (gtk_window_new (GTK_WINDOW_POPUP));
-+
-+ gtk_window_set_type_hint (window, GDK_WINDOW_TYPE_HINT_DOCK);
-+ gtk_window_set_decorated (window, FALSE);
-+ gtk_window_set_resizable (window, FALSE);
-+ gtk_window_stick (window);
-+ gtk_window_set_screen (window, screen);
-+
-+ g_signal_connect (window, "delete_event",
-+ G_CALLBACK (delete_event), cd);
-+
-+ g_signal_connect (window, "key_press_event",
-+ G_CALLBACK (close_on_escape), cd);
-+
-+ vbox_zones = gtk_vbox_new (TRUE, 4);
-+ vbox = gtk_vbox_new (FALSE, 4);
-+ frame = gtk_frame_new (NULL);
-+
-+ gtk_container_add (GTK_CONTAINER (frame), vbox);
-+
-+ for (tmp_list = cd->tip_list;
-+ tmp_list ; tmp_list = tmp_list->next)
-+ {
-+ GtkWidget *zone;
-+ TipZone *tip_zone = tmp_list->data;
-+
-+ zone = add_timezone_button (cd, tip_zone);
-+
-+ gtk_container_add (GTK_CONTAINER (vbox_zones), zone);
-+ }
-+
-+ gtk_container_add (GTK_CONTAINER (vbox), vbox_zones);
-+
-+ separ = gtk_hseparator_new ();
-+ gtk_container_add (GTK_CONTAINER (vbox), separ);
-+
-+ button = gtk_button_new_with_label (_("Edit Time Zones..."));
-+ gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
-+
-+ g_signal_connect (button, "clicked", G_CALLBACK (edit_zones),
-+ cd);
-+
-+ gtk_container_add (GTK_CONTAINER (vbox), button);
-+
-+ gtk_container_add (GTK_CONTAINER (window), frame);
-+
-+ return GTK_WIDGET (window);
-+}
-+
-+
-+static gchar *
-+get_timezone_msgid (TimezoneSelectionDialog *tsd, gchar *zone)
-+{
-+ GPtrArray *locs;
-+ gchar *msgid;
-+ int i;
-+
-+ locs = tz_get_locations (tsd->cd->tzdb);
-+
-+ for (i = 0; i < locs->len; i++)
-+ {
-+ msgid = tz_location_get_zone (g_ptr_array_index (locs, i));
-+
-+ if (!g_utf8_collate (_(msgid), zone))
-+ {
-+ g_free (zone);
-+ return g_strdup (msgid);
-+ }
-+ }
-+
-+ return zone;
-+}
-+
-+static int
-+get_next_available_tips_zone_key_num (TimezoneSelectionDialog *tsd)
-+{
-+ GSList *list = NULL, *li;
-+ int num = -1;
-+ char *tips_store_path = panel_applet_gconf_get_full_key (PANEL_APPLET (tsd->cd->applet), KEY_TIPS_ZONE);
-+
-+
-+ list = gconf_client_all_entries (gconf_client_get_default (), tips_store_path, NULL);
-+
-+ if (list == NULL)
-+ return 0;
-+
-+
-+ for (li = list; li != NULL; li = li->next)
-+ {
-+ GConfEntry *entry = li->data;
-+ char *key_name = g_path_get_basename (gconf_entry_get_key (entry));
-+ int key_num = atoi (key_name);
-+ num = key_num > num ? key_num : num;
-+ }
-+ return num + 1;
-+}
-+
-+enum {
-+ ZONE_COLUMN,
-+ NIK_COLUMN,
-+ EDITABLE_COL,
-+ KEY_NUM_COLUMN,
-+ NUM_COLUMNS
-+};
-+
-+void static
-+on_add_to_tip_button_clicked (GtkWidget * w,
-+ TimezoneSelectionDialog *tsd)
-+{
-+ GtkTreeIter iter;
-+ char *nick;
-+ char *zone = g_strdup (gtk_entry_get_text (GTK_ENTRY (GTK_COMBO ( GW ("location_combo"))->entry)));
-+ int key_num = get_next_available_tips_zone_key_num (tsd);
-+
-+ gtk_tree_store_append (tsd->model, &iter, NULL);
-+
-+ nick = index (zone, '/');
-+ if (nick != NULL)
-+ nick = strdup (nick + 1);
-+ else
-+ nick = strdup (zone);
-+
-+ gtk_tree_store_set (tsd->model, &iter,
-+ ZONE_COLUMN, zone,
-+ NIK_COLUMN, nick,
-+ EDITABLE_COL, TRUE,
-+ KEY_NUM_COLUMN, key_num,
-+ -1);
-+
-+ zone = get_timezone_msgid (tsd, zone);
-+
-+ set_tip_zone_to_gconf (tsd, zone, nick, key_num);
-+
-+ gtk_widget_set_sensitive (GW ("remove_from_tip_button"), TRUE);
-+ gtk_widget_set_sensitive (GW ("add_to_tip_button"), FALSE);
-+
-+ g_free (zone);
-+ update_list_tip_zone (tsd->cd);
-+}
-+
-+void static
-+on_remove_from_tip_button_clicked (GtkWidget *widget,
-+ TimezoneSelectionDialog *tsd)
-+{
-+ GtkTreeIter iter;
-+ GtkTreeModel *model;
-+ gchar *zone, *nick;
-+ GtkTreeSelection *sel;
-+
-+ sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (tsd->tips_tree));
-+
-+ if (gtk_tree_selection_get_selected (sel, &model, &iter))
-+ {
-+ char *path, *key;
-+ int key_num;
-+
-+ gtk_tree_model_get (model, &iter,
-+ ZONE_COLUMN, &zone,
-+ NIK_COLUMN, &nick,
-+ KEY_NUM_COLUMN, &key_num,
-+ -1);
-+
-+ gtk_tree_store_remove (GTK_TREE_STORE (model), &iter);
-+
-+ path = panel_applet_gconf_get_full_key (PANEL_APPLET (tsd->cd->applet),
-+ KEY_TIPS_ZONE);
-+ key = g_strdup_printf ("%s/%d", path, key_num);
-+
-+ gconf_client_unset (gconf_client_get_default (), key, NULL);
-+
-+ g_free (zone);
-+ g_free (nick);
-+ update_list_tip_zone (tsd->cd);
-+ }
-+}
-+
-+static void set_tip_zone_to_gconf (TimezoneSelectionDialog *tsd,
-+ char *zone,
-+ char *nick,
-+ int key_num)
-+{
-+ char *path = panel_applet_gconf_get_full_key (PANEL_APPLET (tsd->cd->applet),
-+ KEY_TIPS_ZONE);
-+
-+ char *key_name = g_strdup_printf ("%s/%d", path, key_num);
-+
-+ gconf_client_set_pair (gconf_client_get_default (),
-+ key_name,
-+ GCONF_VALUE_STRING,
-+ GCONF_VALUE_STRING,
-+ &zone,
-+ &nick,
-+ NULL);
-+ g_free (path);
-+ g_free (key_name);
-+}
-+
-+static void
-+edited (GtkCellRendererText *cell,
-+ gchar *path_string,
-+ gchar *new_text,
-+ TimezoneSelectionDialog *tsd)
-+{
-+ GtkTreeModel *model = GTK_TREE_MODEL (tsd->model);
-+ GtkTreeIter iter;
-+ GtkTreePath *path = gtk_tree_path_new_from_string (path_string);
-+ char *zone;
-+ int key_num;
-+
-+ gtk_tree_model_get_iter (model, &iter, path);
-+
-+ gtk_tree_model_get (model, &iter, ZONE_COLUMN, &zone, KEY_NUM_COLUMN, &key_num, -1);
-+
-+ zone = get_timezone_msgid (tsd, zone);
-+
-+ gtk_tree_store_set (GTK_TREE_STORE (model), &iter, NIK_COLUMN, new_text, -1);
-+
-+ set_tip_zone_to_gconf (tsd, zone, new_text, key_num);
-+
-+ gtk_tree_path_free (path);
-+ g_free (zone);
-+ update_list_tip_zone (tsd->cd);
-+}
-+static void
-+populate_tips_store (TimezoneSelectionDialog *tsd, GtkTreeStore *model)
-+{
-+ char *tips_store_path;
-+ GConfClient *client;
-+ GSList *list = NULL, *li;
-+ GtkTreeIter iter;
-+ client = gconf_client_get_default ();
-+
-+ tips_store_path = panel_applet_gconf_get_full_key (PANEL_APPLET (tsd->cd->applet),
-+ KEY_TIPS_ZONE);
-+
-+ list = gconf_client_all_entries (client, tips_store_path, NULL);
-+
-+ if (!list)
-+ gtk_widget_set_sensitive (GW ("remove_from_tip_button"), FALSE);
-+
-+ for (li = list; li != NULL; li = li->next)
-+ {
-+ char *zone, *nick;
-+ GConfEntry *entry = li->data;
-+ char *key_name = g_path_get_basename (gconf_entry_get_key (entry));
-+ GConfValue *key_value = gconf_entry_get_value (entry);
-+ int key_num = atoi (key_name);
-+
-+ zone = g_strdup (gconf_value_get_string (gconf_value_get_car (key_value)));
-+ nick = g_strdup (gconf_value_get_string (gconf_value_get_cdr (key_value)));
-+
-+ gtk_tree_store_append (model, &iter, NULL);
-+
-+ gtk_tree_store_set (model, &iter,
-+ ZONE_COLUMN, _(zone),
-+ NIK_COLUMN, nick,
-+ EDITABLE_COL, TRUE,
-+ KEY_NUM_COLUMN, key_num,
-+ -1);
-+
-+ g_free (key_name);
-+ g_free (zone);
-+ g_free (nick);
-+ }
-+
-+ g_free (tips_store_path);
-+}
-+
-+void
-+create_multizone_table (TimezoneSelectionDialog *tsd)
-+{
-+ GtkTreeStore *model;
-+ GtkWidget *tree_view;
-+ GtkCellRenderer *renderer;
-+
-+ model = gtk_tree_store_new (NUM_COLUMNS,
-+ G_TYPE_STRING,
-+ G_TYPE_STRING,
-+ G_TYPE_BOOLEAN,
-+ G_TYPE_INT);
-+
-+
-+ populate_tips_store (tsd, model);
-+
-+ tsd->tips_tree = GW ("tips_tree");
-+ tree_view = tsd->tips_tree;
-+ tsd->model = model;
-+
-+ gtk_tree_view_set_model (GTK_TREE_VIEW (tree_view), GTK_TREE_MODEL (model));
-+ gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (tree_view), TRUE);
-+
-+ renderer = gtk_cell_renderer_text_new ();
-+ gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree_view),
-+ -1, _("Time zone"),
-+ renderer,
-+ "text", ZONE_COLUMN,
-+ NULL);
-+ g_signal_connect (renderer, "edited",
-+ G_CALLBACK (edited), model);
-+
-+ renderer = gtk_cell_renderer_text_new ();
-+
-+ gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree_view),
-+ -1, _("Comments"),
-+ renderer,
-+ "text", NIK_COLUMN,
-+ "editable", EDITABLE_COL,
-+ NULL);
-+ g_signal_connect (renderer, "edited",
-+ G_CALLBACK (edited), tsd);
-+
-+ gtk_widget_show (tree_view);
-+
-+ g_signal_connect (G_OBJECT (GW ("add_to_tip_button")), "clicked",
-+ G_CALLBACK (on_add_to_tip_button_clicked), tsd);
-+
-+ g_signal_connect (G_OBJECT (GW ("remove_from_tip_button")), "clicked",
-+ G_CALLBACK (on_remove_from_tip_button_clicked), tsd);
-+
-+
-+}
-+
-+static void free_tip_list (GSList *tips)
-+{
-+ if (tips)
-+ {
-+ GSList *tmp_list;
-+ for (tmp_list = tips; tmp_list ; tmp_list = tmp_list->next)
-+ {
-+ TipZone *tip_tmp = tmp_list->data;
-+ g_free (tip_tmp->zone);
-+ g_free (tip_tmp->nick);
-+ g_free (tip_tmp);
-+ }
-+ g_slist_free (tips);
-+ }
-+}
-+
-+static void
-+update_list_tip_zone (ClockData *cd)
-+{
-+ GSList *list = NULL, *li;
-+
-+ char *tips_store_path = panel_applet_gconf_get_full_key (PANEL_APPLET (cd->applet), KEY_TIPS_ZONE);
-+
-+ free_tip_list (cd->tip_list);
-+ cd->tip_list = NULL;
-+
-+ if (cd->multizone_popup)
-+ {
-+ gtk_widget_destroy (cd->multizone_popup);
-+ cd->multizone_popup = NULL;
-+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cd->multizone_toggle),
-+ FALSE);
-+ }
-+
-+ list = gconf_client_all_entries (gconf_client_get_default (),
-+ tips_store_path, NULL);
-+
-+ if (list == NULL)
-+ return;
-+
-+ for (li = list; li != NULL; li = li->next)
-+ {
-+ GConfEntry *entry = li->data;
-+ GConfValue *key_value = gconf_entry_get_value (entry);
-+ if (key_value)
-+ {
-+ TipZone *tip_zone = g_new (TipZone, 1);
-+ tip_zone->zone = g_strdup (gconf_value_get_string (gconf_value_get_car (key_value)));
-+ tip_zone->nick = g_strdup (gconf_value_get_string (gconf_value_get_cdr (key_value)));
-+ cd->tip_list = g_slist_append (cd->tip_list, tip_zone);
-+ }
-+ }
-+}
-+
-+gboolean
-+multizone_is_zone_in_tip_list (ClockData *cd, char *zone)
-+{
-+ GSList *tmp_list = NULL;
-+ for (tmp_list = cd->tip_list; tmp_list ; tmp_list = tmp_list->next)
-+ {
-+ TipZone *tip_tmp = tmp_list->data;
-+ if (strcmp (tip_tmp->zone, zone) == 0)
-+ return TRUE;
-+ }
-+ return FALSE;
-+}
-+
-+
-diff -Nrup gnome-panel-2.14.1/applets/clock/timezone-selection.c ../gnome-panel-2.14.1/applets/clock/timezone-selection.c
---- gnome-panel-2.14.1/applets/clock/timezone-selection.c 1970-01-01 01:00:00.000000000 +0100
-+++ ../gnome-panel-2.14.1/applets/clock/timezone-selection.c 2006-06-12 16:18:42.524394000 +0200
-@@ -0,0 +1,451 @@
-+#include "config.h"
-+#include "clock.h"
-+
-+
-+#define GW(name) glade_xml_get_widget (tsd->xml, name)
-+
-+static void
-+mark_selected_city (TimezoneSelectionDialog * tsd, gchar * defaultv);
-+
-+static void
-+display_help (GtkWidget * w, gpointer data)
-+{
-+ GError *error = NULL;
-+
-+ gnome_help_display_desktop_on_screen (NULL, "clock", "clock", "clock-usage",
-+ gtk_widget_get_screen (w), &error);
-+
-+ if (error)
-+ {
-+ GtkWidget *dialog;
-+ dialog = gtk_message_dialog_new (GTK_WINDOW (w),
-+ GTK_DIALOG_DESTROY_WITH_PARENT,
-+ GTK_MESSAGE_ERROR,
-+ GTK_BUTTONS_OK,
-+ _("There was an error displaying help: %s"),
-+ error->message);
-+
-+ g_signal_connect (G_OBJECT (dialog), "response",
-+ G_CALLBACK (gtk_widget_destroy), NULL);
-+
-+ gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
-+ gtk_window_set_screen (GTK_WINDOW (dialog), gtk_widget_get_screen (w));
-+ gtk_widget_show (dialog);
-+ g_error_free (error);
-+ }
-+}
-+
-+
-+static TzLocation *
-+tz_location_from_point (TimezoneSelectionDialog * tsd, EMapPoint * point)
-+{
-+ TzLocation *tz_loc = NULL;
-+ GPtrArray *locs;
-+ double p_longitude, p_latitude;
-+ double l_longitude, l_latitude;
-+ int i;
-+
-+ locs = tz_get_locations (tsd->cd->tzdb);
-+ e_map_point_get_location (point, &p_longitude, &p_latitude);
-+
-+ for (i = 0; i < locs->len; i++)
-+ {
-+ tz_location_get_position (g_ptr_array_index (locs, i),
-+ &l_longitude, &l_latitude);
-+
-+ if (l_longitude - 0.005 <= p_longitude &&
-+ l_longitude + 0.005 >= p_longitude &&
-+ l_latitude - 0.005 <= p_latitude &&
-+ l_latitude + 0.005 >= p_latitude)
-+ {
-+ tz_loc = g_ptr_array_index (locs, i);
-+ break;
-+ }
-+ }
-+
-+ return (tz_loc);
-+}
-+
-+static void
-+set_tz_from_name (TimezoneSelectionDialog * tsd, gchar * name)
-+{
-+ TzLocation *tz_loc = NULL;
-+ GPtrArray *locs;
-+ double l_longitude = 0.0, l_latitude = 0.0;
-+ int i;
-+
-+ locs = tz_get_locations (tsd->cd->tzdb);
-+
-+ for (i = 0; i < locs->len; i++)
-+ {
-+ tz_loc = g_ptr_array_index (locs, i);
-+
-+ if (tz_loc
-+ && (!g_utf8_collate (_(tz_location_get_zone (tz_loc)), _(name))))
-+ {
-+ tz_location_get_position (tz_loc, &l_longitude, &l_latitude);
-+ break;
-+ }
-+ }
-+
-+ if (tsd->point_selected)
-+ e_map_point_set_color_rgba (tsd->map,
-+ tsd->point_selected,
-+ TZ_MAP_POINT_NORMAL_RGBA);
-+ tsd->point_selected =
-+ e_map_get_closest_point (tsd->map, l_longitude, l_latitude, FALSE);
-+
-+ gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (GW ("location_combo"))->entry),
-+ _(tz_location_get_zone
-+ (tz_location_from_point (tsd, tsd->point_selected))));
-+}
-+
-+static gchar *
-+get_selected_tz_name (TimezoneSelectionDialog * tsd)
-+{
-+ gchar *entry_text;
-+
-+ entry_text =
-+ (gchar *)
-+ gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (GW ("location_combo"))->entry));
-+
-+ return entry_text;
-+}
-+
-+static gboolean
-+update_map (GtkWidget * w, gpointer data)
-+{
-+ TimezoneSelectionDialog *tsd = (TimezoneSelectionDialog *) data;
-+ char *timezone = (char *) gtk_entry_get_text (GTK_ENTRY (w));
-+
-+ if (strlen (timezone) > 0)
-+ {
-+ gchar *tz_name;
-+ TzLocation *tz_location;
-+
-+ set_tz_from_name (tsd, g_strdup (timezone));
-+
-+ tz_name = get_selected_tz_name (tsd);
-+ tz_location = tz_get_location_by_name (tsd->cd->tzdb, tz_name);
-+ }
-+
-+ gtk_widget_set_sensitive (GW ("add_to_tip_button"),
-+ !multizone_is_zone_in_tip_list(tsd->cd, timezone));
-+
-+ return TRUE;
-+}
-+
-+static gboolean
-+out_map (GtkWidget * w, GdkEventCrossing * event, gpointer data)
-+{
-+ const char *old_zone;
-+ TimezoneSelectionDialog *tsd = (TimezoneSelectionDialog *) data;
-+ GtkWidget *location_label = GW ("location_label");
-+
-+ if (event->mode != GDK_CROSSING_NORMAL)
-+ return FALSE;
-+
-+ if (tsd->point_hover && tsd->point_hover != tsd->point_selected)
-+ e_map_point_set_color_rgba (tsd->map, tsd->point_hover,
-+ TZ_MAP_POINT_NORMAL_RGBA);
-+
-+ tsd->point_hover = NULL;
-+
-+ old_zone = gtk_label_get_text (GTK_LABEL (location_label));
-+
-+ if (strcmp (old_zone, ""))
-+ {
-+ gtk_label_set_text (GTK_LABEL (location_label), "");
-+ gtk_label_set_text (GTK_LABEL (GW ("time_clock_label")), "");
-+ }
-+
-+ return TRUE;
-+}
-+
-+static gboolean
-+button_pressed (GtkWidget * w, GdkEventButton * event, gpointer data)
-+{
-+ double longitude, latitude;
-+ TimezoneSelectionDialog *tsd = (TimezoneSelectionDialog *) data;
-+ GtkWidget *zoom_label = GW ("zoom_label");
-+
-+ e_map_window_to_world (tsd->map, (double) event->x, (double) event->y,
-+ &longitude, &latitude);
-+
-+ if (event->button != 1)
-+ {
-+ e_map_zoom_out (tsd->map);
-+ gtk_label_set_text (GTK_LABEL (zoom_label),
-+ _("Click on your nearest city or select it from the list (left click to zoom in):"));
-+ }
-+ else
-+ {
-+ GtkWidget *location_entry;
-+ TzLocation *tz_location;
-+ gchar *entry_text, *entry_text_new;
-+
-+ if (e_map_get_magnification (tsd->map) <= 1.0)
-+ e_map_zoom_to_location (tsd->map, longitude, latitude);
-+
-+ if (tsd->point_selected)
-+ e_map_point_set_color_rgba (tsd->map,
-+ tsd->point_selected,
-+ TZ_MAP_POINT_NORMAL_RGBA);
-+ tsd->point_selected = tsd->point_hover;
-+
-+ location_entry = GTK_COMBO (GW ("location_combo"))->entry;
-+ tz_location = tz_location_from_point (tsd, tsd->point_selected);
-+
-+ entry_text = (gchar *) gtk_entry_get_text (GTK_ENTRY (location_entry));
-+ entry_text_new = _(tz_location_get_zone (tz_location));
-+
-+
-+ if (!entry_text || !entry_text_new
-+ || g_utf8_collate (entry_text, entry_text_new))
-+ {
-+ gtk_entry_set_text (GTK_ENTRY (location_entry), entry_text_new);
-+ gtk_widget_set_sensitive (GW ("add_to_tip_button"),
-+ !multizone_is_zone_in_tip_list(tsd->cd, entry_text_new));
-+ }
-+ gtk_label_set_text (GTK_LABEL (zoom_label),
-+ _("Click on your nearest city or select it from the list (right click to zoom out):"));
-+ mark_selected_city (tsd, entry_text_new);
-+ }
-+
-+ return TRUE;
-+}
-+
-+static gboolean
-+motion (GtkWidget * widget, GdkEventMotion * event, gpointer data)
-+{
-+ TimezoneSelectionDialog *tsd = (TimezoneSelectionDialog *) data;
-+ double longitude, latitude;
-+ GtkWidget *time_label = GW ("time_clock_label");
-+ GtkWidget *location_label = GW ("location_label");
-+
-+
-+ e_map_window_to_world (tsd->map, (double) event->x, (double) event->y,
-+ &longitude, &latitude);
-+
-+ if (tsd->point_hover && tsd->point_hover != tsd->point_selected)
-+ e_map_point_set_color_rgba (tsd->map, tsd->point_hover,
-+ TZ_MAP_POINT_NORMAL_RGBA);
-+
-+ tsd->point_hover =
-+ e_map_get_closest_point (tsd->map, longitude, latitude, TRUE);
-+
-+ if (tsd->point_hover != tsd->point_selected)
-+ e_map_point_set_color_rgba (tsd->map, tsd->point_hover,
-+ TZ_MAP_POINT_HOVER_RGBA);
-+
-+ tsd->correction =
-+ tz_location_get_utc_offset (tz_location_from_point
-+ (tsd, tsd->point_hover));
-+
-+ /* e_tz_map_location_from_point() can in theory return NULL, but in
-+ * practice there are no reasons why it should */
-+
-+ gtk_label_set_text (GTK_LABEL (location_label),
-+ _(tz_location_get_zone
-+ (tz_location_from_point (tsd, tsd->point_hover))));
-+
-+ if (strcmp (gtk_label_get_text (GTK_LABEL (location_label)), "") == 0)
-+ {
-+ gtk_label_set_text (GTK_LABEL (time_label), "");
-+ }
-+ else
-+ {
-+ struct tm tm;
-+ time_t tt;
-+ char clock[256];
-+
-+ time (&tt);
-+ tt += tsd->correction;
-+ gmtime_r (&tt, &tm);
-+ memset (clock, 0, 256);
-+ sprintf (clock, "%02d:%02d:%02d", tm.tm_hour, tm.tm_min, tm.tm_sec);
-+ gtk_label_set_text (GTK_LABEL (time_label), clock);
-+ }
-+
-+
-+ return TRUE;
-+}
-+
-+static gboolean
-+flash_selected_point (gpointer data)
-+{
-+ TimezoneSelectionDialog *tsd = (TimezoneSelectionDialog *) data;
-+
-+ if (!IS_E_MAP (tsd->map))
-+ return FALSE;
-+
-+ if (!tsd->point_selected)
-+ return TRUE;
-+
-+ if (e_map_point_get_color_rgba (tsd->point_selected) ==
-+ TZ_MAP_POINT_SELECTED_1_RGBA)
-+ e_map_point_set_color_rgba (tsd->map, tsd->point_selected,
-+ TZ_MAP_POINT_SELECTED_2_RGBA);
-+ else
-+ e_map_point_set_color_rgba (tsd->map, tsd->point_selected,
-+ TZ_MAP_POINT_SELECTED_1_RGBA);
-+
-+ return TRUE;
-+}
-+
-+
-+static void
-+mark_selected_city (TimezoneSelectionDialog * tsd, gchar * defaultv)
-+{
-+ TzLocation *tz_loc = NULL;
-+ GPtrArray *locs;
-+ int i;
-+ double l_longitude = 0.0, l_latitude = 0.0;
-+ char *system_timezone = tz_get_system_timezone ();
-+
-+ if (!defaultv || !strcmp ("localtimezone", defaultv))
-+ tsd->zone = g_strdup (system_timezone);
-+ else
-+ {
-+ g_free (tsd->zone);
-+ tsd->zone = g_strdup (defaultv);
-+ }
-+
-+ locs = tz_get_locations (tsd->cd->tzdb);
-+
-+ for (i = 0; i < locs->len; i++)
-+ {
-+ tz_loc = g_ptr_array_index (locs, i);
-+
-+ if (tz_loc
-+ &&
-+ (!g_utf8_collate (_(tz_location_get_zone (tz_loc)), _(tsd->zone))))
-+ {
-+ tz_location_get_position (tz_loc, &l_longitude, &l_latitude);
-+ break;
-+ }
-+ }
-+
-+ if (tsd->point_selected)
-+ e_map_point_set_color_rgba (tsd->map,
-+ tsd->point_selected,
-+ TZ_MAP_POINT_NORMAL_RGBA);
-+ tsd->point_selected =
-+ e_map_get_closest_point (tsd->map, l_longitude, l_latitude, FALSE);
-+
-+ gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (GW ("location_combo"))->entry),
-+ _(tz_location_get_zone (tz_location_from_point
-+ (tsd, tsd->point_selected))));
-+}
-+
-+static void
-+reset_zone (GtkWidget * w, TimezoneSelectionDialog * tsd)
-+{
-+ char *current_zone = tz_get_system_timezone ();
-+
-+ mark_selected_city (tsd, current_zone);
-+
-+ g_free (current_zone);
-+}
-+
-+void
-+display_timezone_selection_dialog (BonoboUIComponent *uic,
-+ ClockData *cd,
-+ const gchar *verbname)
-+{
-+ GtkWidget *location_entry;
-+ GPtrArray *locs;
-+ GList *items = NULL;
-+ int i;
-+ TimezoneSelectionDialog *tsd;
-+
-+ if (cd->timezone_dialog)
-+ {
-+ gtk_window_set_screen (GTK_WINDOW (cd->timezone_dialog),
-+ gtk_widget_get_screen (cd->applet));
-+ gtk_window_present (GTK_WINDOW (cd->timezone_dialog));
-+ e_map_zoom_out (cd->tsd->map);
-+ return;
-+ }
-+
-+ tsd = g_new0 (TimezoneSelectionDialog, 1);
-+
-+ tsd->cd = cd;
-+ cd->tsd = tsd;
-+
-+ tsd->xml = glade_xml_new (GLADEDIR "/timezone.glade", NULL, NULL);
-+
-+ if (tsd->xml == NULL)
-+ {
-+ g_warning (G_STRLOC "timezone.glade cannot be found");
-+ return;
-+ }
-+ glade_xml_signal_autoconnect (tsd->xml);
-+
-+ tsd->map = e_map_new ();
-+
-+ e_map_set_smooth_zoom (tsd->map, TRUE);
-+
-+ gtk_widget_set_events (GTK_WIDGET (tsd->map),
-+ gtk_widget_get_events (GTK_WIDGET (tsd->map)) |
-+ GDK_LEAVE_NOTIFY_MASK | GDK_VISIBILITY_NOTIFY_MASK);
-+
-+ gtk_container_add (GTK_CONTAINER (GW ("map_window")),
-+ GTK_WIDGET (tsd->map));
-+ gtk_widget_show (GTK_WIDGET (tsd->map));
-+
-+
-+ if (!cd->tzdb)
-+ cd->tzdb = tz_load_db ();
-+ if (!cd->tzdb)
-+ {
-+ g_warning (G_STRLOC "Unable to load system timezone database.");
-+ return;
-+ }
-+
-+ locs = tz_get_locations (cd->tzdb);
-+
-+ for (i = 0; g_ptr_array_index (locs, i); i++)
-+ {
-+ TzLocation *tzl;
-+ tzl = g_ptr_array_index (locs, i);
-+ e_map_add_point (tsd->map, NULL, tzl->longitude, tzl->latitude,
-+ TZ_MAP_POINT_NORMAL_RGBA);
-+ items = g_list_append (items, _(tzl->zone));
-+ }
-+
-+ gtk_combo_set_popdown_strings (GTK_COMBO (GW ("location_combo")), items);
-+
-+ mark_selected_city (tsd, "localtimezone");
-+
-+ tsd->timeout = g_timeout_add (100, flash_selected_point, (gpointer) tsd);
-+
-+ g_signal_connect (G_OBJECT (tsd->map), "motion-notify-event",
-+ G_CALLBACK (motion), (gpointer) tsd);
-+ g_signal_connect (G_OBJECT (tsd->map), "button-press-event",
-+ G_CALLBACK (button_pressed), (gpointer) tsd);
-+ g_signal_connect (G_OBJECT (tsd->map), "leave-notify-event",
-+ G_CALLBACK (out_map), (gpointer) tsd);
-+
-+ location_entry = GTK_COMBO (GW ("location_combo"))->entry;
-+ g_signal_connect (G_OBJECT (location_entry), "changed",
-+ G_CALLBACK (update_map), (gpointer) tsd);
-+
-+ g_signal_connect (G_OBJECT (GW ("reset_button")), "clicked",
-+ G_CALLBACK (reset_zone), tsd);
-+
-+ g_signal_connect (G_OBJECT (GW ("helpbutton")), "clicked",
-+ G_CALLBACK (display_help), tsd);
-+
-+ tsd->dialog = GW ("timezone_dialog");
-+ cd->timezone_dialog = tsd->dialog;
-+
-+ gtk_window_set_screen (GTK_WINDOW (cd->timezone_dialog),
-+ gtk_widget_get_screen (cd->applet));
-+
-+ create_multizone_table (tsd);
-+
-+ gtk_widget_show_all (cd->timezone_dialog);
-+
-+}
-+
-diff -Nrup gnome-panel-2.14.1/applets/clock/timezone.glade ../gnome-panel-2.14.1/applets/clock/timezone.glade
---- gnome-panel-2.14.1/applets/clock/timezone.glade 1970-01-01 01:00:00.000000000 +0100
-+++ ../gnome-panel-2.14.1/applets/clock/timezone.glade 2006-06-12 16:18:42.525014000 +0200
-@@ -0,0 +1,622 @@
-+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
-+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
-+
-+<glade-interface>
-+<requires lib="gnome"/>
-+
-+<widget class="GtkDialog" id="timezone_dialog">
-+ <property name="width_request">545</property>
-+ <property name="height_request">575</property>
-+ <property name="title" translatable="yes">Change Clock Applet Time Zone</property>
-+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
-+ <property name="window_position">GTK_WIN_POS_NONE</property>
-+ <property name="modal">False</property>
-+ <property name="resizable">True</property>
-+ <property name="destroy_with_parent">False</property>
-+ <property name="decorated">True</property>
-+ <property name="skip_taskbar_hint">False</property>
-+ <property name="skip_pager_hint">False</property>
-+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
-+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
-+ <property name="focus_on_map">True</property>
-+ <property name="urgency_hint">False</property>
-+ <property name="has_separator">True</property>
-+ <signal name="delete_event" handler="gtk_widget_hide" last_modification_time="Thu, 20 Nov 2003 16:52:00 GMT"/>
-+ <signal name="destroy_event" handler="gtk_widget_hide" last_modification_time="Thu, 20 Nov 2003 16:52:19 GMT"/>
-+
-+ <child internal-child="vbox">
-+ <widget class="GtkVBox" id="dialog-vbox3">
-+ <property name="width_request">635</property>
-+ <property name="height_request">384</property>
-+ <property name="visible">True</property>
-+ <property name="homogeneous">False</property>
-+ <property name="spacing">0</property>
-+
-+ <child internal-child="action_area">
-+ <widget class="GtkHButtonBox" id="dialog-action_area3">
-+ <property name="visible">True</property>
-+ <property name="layout_style">GTK_BUTTONBOX_END</property>
-+
-+ <child>
-+ <widget class="GtkButton" id="helpbutton">
-+ <property name="visible">True</property>
-+ <property name="can_default">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="label">gtk-help</property>
-+ <property name="use_stock">True</property>
-+ <property name="relief">GTK_RELIEF_NORMAL</property>
-+ <property name="focus_on_click">True</property>
-+ <property name="response_id">-11</property>
-+ </widget>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkButton" id="timezone_apply_button">
-+ <property name="visible">True</property>
-+ <property name="can_default">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="label">gtk-close</property>
-+ <property name="use_stock">True</property>
-+ <property name="relief">GTK_RELIEF_NORMAL</property>
-+ <property name="focus_on_click">True</property>
-+ <property name="response_id">-7</property>
-+ <signal name="clicked" handler="gtk_widget_hide" object="timezone_dialog" last_modification_time="Thu, 20 Nov 2003 17:54:21 GMT"/>
-+ </widget>
-+ </child>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ <property name="pack_type">GTK_PACK_END</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkVBox" id="time_zone_dialog_content">
-+ <property name="border_width">12</property>
-+ <property name="visible">True</property>
-+ <property name="homogeneous">False</property>
-+ <property name="spacing">12</property>
-+
-+ <child>
-+ <widget class="GtkLabel" id="zoom_label">
-+ <property name="visible">True</property>
-+ <property name="label" translatable="yes">Click on your nearest city or select it from the list (left click to zoom in):</property>
-+ <property name="use_underline">False</property>
-+ <property name="use_markup">True</property>
-+ <property name="justify">GTK_JUSTIFY_LEFT</property>
-+ <property name="wrap">False</property>
-+ <property name="selectable">False</property>
-+ <property name="xalign">0</property>
-+ <property name="yalign">0.5</property>
-+ <property name="xpad">0</property>
-+ <property name="ypad">0</property>
-+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-+ <property name="width_chars">-1</property>
-+ <property name="single_line_mode">False</property>
-+ <property name="angle">0</property>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkVBox" id="timezone_vbox">
-+ <property name="width_request">335</property>
-+ <property name="height_request">337</property>
-+ <property name="visible">True</property>
-+ <property name="homogeneous">False</property>
-+ <property name="spacing">12</property>
-+
-+ <child>
-+ <widget class="GtkScrolledWindow" id="map_window">
-+ <property name="width_request">60</property>
-+ <property name="height_request">230</property>
-+ <property name="visible">True</property>
-+ <property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property>
-+ <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
-+ <property name="shadow_type">GTK_SHADOW_IN</property>
-+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
-+
-+ <child>
-+ <placeholder/>
-+ </child>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">True</property>
-+ <property name="fill">True</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkHBox" id="hbox52">
-+ <property name="visible">True</property>
-+ <property name="homogeneous">True</property>
-+ <property name="spacing">0</property>
-+
-+ <child>
-+ <widget class="GtkLabel" id="location_label">
-+ <property name="visible">True</property>
-+ <property name="label" translatable="yes"></property>
-+ <property name="use_underline">False</property>
-+ <property name="use_markup">False</property>
-+ <property name="justify">GTK_JUSTIFY_LEFT</property>
-+ <property name="wrap">False</property>
-+ <property name="selectable">False</property>
-+ <property name="xalign">0</property>
-+ <property name="yalign">0.5</property>
-+ <property name="xpad">0</property>
-+ <property name="ypad">11</property>
-+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-+ <property name="width_chars">-1</property>
-+ <property name="single_line_mode">False</property>
-+ <property name="angle">0</property>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkLabel" id="time_clock_label">
-+ <property name="visible">True</property>
-+ <property name="label" translatable="yes"></property>
-+ <property name="use_underline">False</property>
-+ <property name="use_markup">False</property>
-+ <property name="justify">GTK_JUSTIFY_RIGHT</property>
-+ <property name="wrap">False</property>
-+ <property name="selectable">False</property>
-+ <property name="xalign">1</property>
-+ <property name="yalign">0.5</property>
-+ <property name="xpad">0</property>
-+ <property name="ypad">0</property>
-+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-+ <property name="width_chars">-1</property>
-+ <property name="single_line_mode">False</property>
-+ <property name="angle">0</property>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ </packing>
-+ </child>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkHBox" id="hbox_main_zone">
-+ <property name="visible">True</property>
-+ <property name="homogeneous">False</property>
-+ <property name="spacing">19</property>
-+
-+ <child>
-+ <widget class="GtkLabel" id="label45">
-+ <property name="visible">True</property>
-+ <property name="label" translatable="yes">Time _zone:</property>
-+ <property name="use_underline">True</property>
-+ <property name="use_markup">False</property>
-+ <property name="justify">GTK_JUSTIFY_CENTER</property>
-+ <property name="wrap">False</property>
-+ <property name="selectable">False</property>
-+ <property name="xalign">0.5</property>
-+ <property name="yalign">0.5</property>
-+ <property name="xpad">0</property>
-+ <property name="ypad">0</property>
-+ <property name="mnemonic_widget">entry_location</property>
-+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-+ <property name="width_chars">-1</property>
-+ <property name="single_line_mode">False</property>
-+ <property name="angle">0</property>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkCombo" id="location_combo">
-+ <property name="visible">True</property>
-+ <property name="value_in_list">False</property>
-+ <property name="allow_empty">False</property>
-+ <property name="case_sensitive">False</property>
-+ <property name="enable_arrow_keys">True</property>
-+ <property name="enable_arrows_always">True</property>
-+
-+ <child internal-child="entry">
-+ <widget class="GtkEntry" id="entry_location">
-+ <property name="visible">True</property>
-+ <property name="editable">False</property>
-+ <property name="visibility">True</property>
-+ <property name="max_length">0</property>
-+ <property name="text" translatable="yes"></property>
-+ <property name="has_frame">True</property>
-+ <property name="invisible_char">*</property>
-+ <property name="activates_default">False</property>
-+ </widget>
-+ </child>
-+
-+ <child internal-child="list">
-+ <widget class="GtkList" id="convertwidget5">
-+ <property name="visible">True</property>
-+ <property name="selection_mode">GTK_SELECTION_BROWSE</property>
-+
-+ <child>
-+ <widget class="GtkListItem" id="convertwidget6">
-+ <property name="visible">True</property>
-+
-+ <child>
-+ <widget class="GtkLabel" id="convertwidget7">
-+ <property name="visible">True</property>
-+ <property name="label" translatable="yes"></property>
-+ <property name="use_underline">False</property>
-+ <property name="use_markup">False</property>
-+ <property name="justify">GTK_JUSTIFY_LEFT</property>
-+ <property name="wrap">False</property>
-+ <property name="selectable">False</property>
-+ <property name="xalign">0</property>
-+ <property name="yalign">0.5</property>
-+ <property name="xpad">0</property>
-+ <property name="ypad">0</property>
-+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-+ <property name="width_chars">-1</property>
-+ <property name="single_line_mode">False</property>
-+ <property name="angle">0</property>
-+ </widget>
-+ </child>
-+ </widget>
-+ </child>
-+ </widget>
-+ </child>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">True</property>
-+ <property name="fill">True</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <placeholder/>
-+ </child>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ </packing>
-+ </child>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">True</property>
-+ <property name="fill">True</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkHSeparator" id="hseparator_main_zone">
-+ <property name="visible">True</property>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">True</property>
-+ <property name="fill">True</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkHBox" id="tip_options_vbox">
-+ <property name="homogeneous">False</property>
-+ <property name="spacing">6</property>
-+
-+ <child>
-+ <widget class="GtkVBox" id="vbox27">
-+ <property name="visible">True</property>
-+ <property name="homogeneous">False</property>
-+ <property name="spacing">0</property>
-+
-+ <child>
-+ <widget class="GtkLabel" id="label127">
-+ <property name="visible">True</property>
-+ <property name="label" translatable="yes">_List:</property>
-+ <property name="use_underline">True</property>
-+ <property name="use_markup">False</property>
-+ <property name="justify">GTK_JUSTIFY_LEFT</property>
-+ <property name="wrap">False</property>
-+ <property name="selectable">False</property>
-+ <property name="xalign">0.5</property>
-+ <property name="yalign">0.5</property>
-+ <property name="xpad">0</property>
-+ <property name="ypad">0</property>
-+ <property name="mnemonic_widget">scrolledwindow1</property>
-+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-+ <property name="width_chars">-1</property>
-+ <property name="single_line_mode">False</property>
-+ <property name="angle">0</property>
-+ </widget>
-+ <packing>
-+ <property name="padding">4</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <placeholder/>
-+ </child>
-+
-+ <child>
-+ <placeholder/>
-+ </child>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkScrolledWindow" id="scrolledwindow1">
-+ <property name="visible">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-+ <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
-+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
-+
-+ <child>
-+ <widget class="GtkTreeView" id="tips_tree">
-+ <property name="visible">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="headers_visible">True</property>
-+ <property name="rules_hint">False</property>
-+ <property name="reorderable">False</property>
-+ <property name="enable_search">True</property>
-+ <property name="fixed_height_mode">False</property>
-+ <property name="hover_selection">False</property>
-+ <property name="hover_expand">False</property>
-+ </widget>
-+ </child>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">True</property>
-+ <property name="fill">True</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkVBox" id="vbox26">
-+ <property name="visible">True</property>
-+ <property name="homogeneous">False</property>
-+ <property name="spacing">0</property>
-+
-+ <child>
-+ <placeholder/>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkButton" id="add_to_tip_button">
-+ <property name="visible">True</property>
-+ <property name="can_default">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="relief">GTK_RELIEF_NORMAL</property>
-+ <property name="focus_on_click">True</property>
-+
-+ <child>
-+ <widget class="GtkAlignment" id="alignment2">
-+ <property name="visible">True</property>
-+ <property name="xalign">0.5</property>
-+ <property name="yalign">0.5</property>
-+ <property name="xscale">0</property>
-+ <property name="yscale">0</property>
-+ <property name="top_padding">0</property>
-+ <property name="bottom_padding">0</property>
-+ <property name="left_padding">0</property>
-+ <property name="right_padding">0</property>
-+
-+ <child>
-+ <widget class="GtkHBox" id="hbox53">
-+ <property name="visible">True</property>
-+ <property name="homogeneous">False</property>
-+ <property name="spacing">2</property>
-+
-+ <child>
-+ <widget class="GtkImage" id="image2">
-+ <property name="visible">True</property>
-+ <property name="stock">gtk-add</property>
-+ <property name="icon_size">4</property>
-+ <property name="xalign">0.5</property>
-+ <property name="yalign">0.5</property>
-+ <property name="xpad">0</property>
-+ <property name="ypad">0</property>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkLabel" id="label122">
-+ <property name="visible">True</property>
-+ <property name="label" translatable="yes">_Add</property>
-+ <property name="use_underline">True</property>
-+ <property name="use_markup">False</property>
-+ <property name="justify">GTK_JUSTIFY_LEFT</property>
-+ <property name="wrap">False</property>
-+ <property name="selectable">False</property>
-+ <property name="xalign">0.5</property>
-+ <property name="yalign">0.5</property>
-+ <property name="xpad">0</property>
-+ <property name="ypad">0</property>
-+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-+ <property name="width_chars">-1</property>
-+ <property name="single_line_mode">False</property>
-+ <property name="angle">0</property>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ </packing>
-+ </child>
-+ </widget>
-+ </child>
-+ </widget>
-+ </child>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">True</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkLabel" id="label129">
-+ <property name="visible">True</property>
-+ <property name="label" translatable="yes"></property>
-+ <property name="use_underline">False</property>
-+ <property name="use_markup">False</property>
-+ <property name="justify">GTK_JUSTIFY_LEFT</property>
-+ <property name="wrap">False</property>
-+ <property name="selectable">False</property>
-+ <property name="xalign">0.5</property>
-+ <property name="yalign">0.5</property>
-+ <property name="xpad">0</property>
-+ <property name="ypad">0</property>
-+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-+ <property name="width_chars">-1</property>
-+ <property name="single_line_mode">False</property>
-+ <property name="angle">0</property>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkButton" id="remove_from_tip_button">
-+ <property name="visible">True</property>
-+ <property name="can_default">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="relief">GTK_RELIEF_NORMAL</property>
-+ <property name="focus_on_click">True</property>
-+
-+ <child>
-+ <widget class="GtkAlignment" id="alignment3">
-+ <property name="visible">True</property>
-+ <property name="xalign">0.5</property>
-+ <property name="yalign">0.5</property>
-+ <property name="xscale">0</property>
-+ <property name="yscale">0</property>
-+ <property name="top_padding">0</property>
-+ <property name="bottom_padding">0</property>
-+ <property name="left_padding">0</property>
-+ <property name="right_padding">0</property>
-+
-+ <child>
-+ <widget class="GtkHBox" id="hbox57">
-+ <property name="visible">True</property>
-+ <property name="homogeneous">False</property>
-+ <property name="spacing">2</property>
-+
-+ <child>
-+ <widget class="GtkImage" id="image3">
-+ <property name="visible">True</property>
-+ <property name="stock">gtk-remove</property>
-+ <property name="icon_size">4</property>
-+ <property name="xalign">0.5</property>
-+ <property name="yalign">0.5</property>
-+ <property name="xpad">0</property>
-+ <property name="ypad">0</property>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkLabel" id="label124">
-+ <property name="visible">True</property>
-+ <property name="label" translatable="yes">_Remove</property>
-+ <property name="use_underline">True</property>
-+ <property name="use_markup">False</property>
-+ <property name="justify">GTK_JUSTIFY_LEFT</property>
-+ <property name="wrap">False</property>
-+ <property name="selectable">False</property>
-+ <property name="xalign">0.5</property>
-+ <property name="yalign">0.5</property>
-+ <property name="xpad">0</property>
-+ <property name="ypad">0</property>
-+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-+ <property name="width_chars">-1</property>
-+ <property name="single_line_mode">False</property>
-+ <property name="angle">0</property>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ </packing>
-+ </child>
-+ </widget>
-+ </child>
-+ </widget>
-+ </child>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">True</property>
-+ <property name="fill">False</property>
-+ </packing>
-+ </child>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ <property name="pack_type">GTK_PACK_END</property>
-+ </packing>
-+ </child>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">True</property>
-+ <property name="fill">True</property>
-+ </packing>
-+ </child>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">True</property>
-+ <property name="fill">True</property>
-+ </packing>
-+ </child>
-+ </widget>
-+ </child>
-+</widget>
-+
-+</glade-interface>
-diff -Nrup gnome-panel-2.14.1/applets/clock/tz.c ../gnome-panel-2.14.1/applets/clock/tz.c
---- gnome-panel-2.14.1/applets/clock/tz.c 1970-01-01 01:00:00.000000000 +0100
-+++ ../gnome-panel-2.14.1/applets/clock/tz.c 2006-06-12 16:18:42.719390000 +0200
-@@ -0,0 +1,499 @@
-+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-+/* Generic timezone utilities.
-+ *
-+ * Copyright (C) 2000-2001 Ximian, Inc.
-+ * Copyright (C) 2004 Sun Microsystems, Inc.
-+ *
-+ * Authors: Hans Petter Jansson <[email protected]>
-+ * additional functions by Erwann Chenede <[email protected]>
-+ *
-+ * Largely based on Michael Fulbright's work on Anaconda.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
-+ */
-+
-+#include "tz.h"
-+
-+/* Forward declarations for private functions */
-+
-+static float convert_pos (gchar * pos, int digits);
-+static int compare_country_names (const void *a, const void *b);
-+static void sort_locations_by_country (GPtrArray * locations);
-+static gchar *tz_data_file_get (void);
-+
-+extern char **environ;
-+#ifdef HAVE_SOLARIS
-+extern time_t timezone;
-+extern char *tzname[2];
-+#endif
-+
-+/* ---------------- *
-+ * Public interface *
-+ * ---------------- */
-+
-+struct tm *
-+tz_get_localtime_at (const char *zone,
-+ const time_t *now)
-+{
-+ char **environ_old;
-+ char **envp;
-+ struct tm *retval;
-+ int i, env_len, tz_index;
-+
-+ tz_index = -1;
-+ for (env_len = 0; environ [env_len]; env_len++)
-+ if (!strncmp (environ [env_len], "TZ=", strlen ("TZ=")))
-+ tz_index = env_len;
-+
-+ if (tz_index == -1)
-+ tz_index = env_len++;
-+
-+ envp = g_new0 (char *, env_len + 1);
-+
-+ for (i = 0; i < env_len; i++)
-+ if (i == tz_index)
-+ envp [i] = g_strconcat ("TZ=", zone, NULL);
-+ else
-+ envp [i] = g_strdup (environ [i]);
-+
-+ environ_old = environ;
-+ environ = envp;
-+
-+ retval = localtime (now);
-+
-+ environ = environ_old;
-+ g_strfreev (envp);
-+
-+ return retval;
-+}
-+
-+TzDB *
-+tz_load_db (void)
-+{
-+ gchar *tz_data_file;
-+ TzDB *tz_db;
-+ FILE *tzfile;
-+ char buf[4096];
-+
-+ tz_data_file = tz_data_file_get ();
-+ if (!tz_data_file)
-+ {
-+ g_warning ("Could not get the TimeZone data file name");
-+ return NULL;
-+ }
-+ tzfile = fopen (tz_data_file, "r");
-+ if (!tzfile)
-+ {
-+ g_warning ("Could not open *%s*\n", tz_data_file);
-+ g_free (tz_data_file);
-+ return NULL;
-+ }
-+
-+ tz_db = g_new0 (TzDB, 1);
-+ tz_db->locations = g_ptr_array_new ();
-+
-+ while (fgets (buf, sizeof (buf), tzfile))
-+ {
-+ gchar **tmpstrarr;
-+ gchar *latstr, *lngstr, *p;
-+ TzLocation *loc;
-+
-+ if (*buf == '#')
-+ continue;
-+
-+ g_strchomp (buf);
-+ tmpstrarr = g_strsplit (buf, "\t", 4);
-+
-+ latstr = g_strdup (tmpstrarr[1]);
-+ p = latstr + 1;
-+ while (*p != '-' && *p != '+')
-+ p++;
-+ lngstr = g_strdup (p);
-+ *p = '\0';
-+
-+ loc = g_new (TzLocation, 1);
-+ loc->country = g_strdup (tmpstrarr[0]);
-+ loc->zone = g_strdup (tmpstrarr[2]);
-+ loc->comment = (tmpstrarr[3]) ? g_strdup (tmpstrarr[3]) : NULL;
-+ loc->latitude = convert_pos (latstr, 2);
-+ loc->longitude = convert_pos (lngstr, 3);
-+
-+ g_ptr_array_add (tz_db->locations, (gpointer) loc);
-+
-+ g_free (latstr);
-+ g_free (lngstr);
-+ g_strfreev (tmpstrarr);
-+ }
-+
-+ fclose (tzfile);
-+
-+ /* now sort by country */
-+ sort_locations_by_country (tz_db->locations);
-+
-+ /* added a NULL pointer at the end of the array to prevent errors. Carlos */
-+ g_ptr_array_add (tz_db->locations, (gpointer) NULL);
-+
-+ g_free (tz_data_file);
-+
-+ return tz_db;
-+}
-+void
-+tz_location_free (TzLocation * tz)
-+{
-+
-+ if (tz->country)
-+ g_free (tz->country);
-+ if (tz->zone)
-+ g_free (tz->zone);
-+ if (tz->comment)
-+ g_free (tz->comment);
-+
-+ g_free (tz);
-+}
-+
-+void
-+tz_free_db (TzDB *tz_db)
-+{
-+ int i;
-+ for (i = 0; g_ptr_array_index (tz_db->locations, i); i++)
-+ {
-+ TzLocation *loc = g_ptr_array_index (tz_db->locations, i);
-+ tz_location_free (loc);
-+ }
-+ g_ptr_array_free (tz_db->locations, FALSE);
-+ g_free (tz_db);
-+}
-+
-+GPtrArray *
-+tz_get_locations (TzDB * db)
-+{
-+ return db->locations;
-+}
-+
-+
-+gchar *
-+tz_location_get_country (TzLocation * loc)
-+{
-+ return loc->country;
-+}
-+
-+
-+gchar *
-+tz_location_get_zone (TzLocation * loc)
-+{
-+ return loc->zone;
-+}
-+
-+
-+gchar *
-+tz_location_get_comment (TzLocation * loc)
-+{
-+ return loc->comment;
-+}
-+
-+
-+void
-+tz_location_get_position (TzLocation * loc, double *longitude,
-+ double *latitude)
-+{
-+ *longitude = loc->longitude;
-+ *latitude = loc->latitude;
-+}
-+
-+
-+
-+
-+TzInfo *
-+tz_info_from_location (TzLocation * loc)
-+{
-+ TzInfo *tzinfo;
-+ time_t curtime;
-+ struct tm *curzone;
-+
-+ g_return_val_if_fail (loc != NULL, NULL);
-+ g_return_val_if_fail (loc->zone != NULL, NULL);
-+
-+ tzinfo = g_new0 (TzInfo, 1);
-+
-+ curtime = time (NULL);
-+ curzone = tz_get_localtime_at (loc->zone, &curtime);
-+#if 0
-+ g_print ("%s %s %d\n", curzone->tm_zone,
-+ &curzone->tm_zone[curzone->tm_isdst], curzone->tm_isdst);
-+#endif
-+
-+#ifdef HAVE_LINUX
-+ tzinfo->tzname_normal = g_strdup (curzone->tm_zone);
-+ if (curzone->tm_isdst)
-+ tzinfo->tzname_daylight = g_strdup (&curzone->tm_zone[curzone->tm_isdst]);
-+ else
-+ tzinfo->tzname_daylight = NULL;
-+
-+ tzinfo->utc_offset = curzone->tm_gmtoff;
-+#endif
-+
-+
-+#ifdef HAVE_SOLARIS
-+ tzinfo->tzname_normal = g_strdup (loc->zone);
-+
-+ if (curzone->tm_isdst)
-+ tzinfo->tzname_daylight = g_strdup (tzname[0]);
-+ else
-+ tzinfo->tzname_daylight = NULL;
-+
-+ tzinfo->utc_offset -= (timezone - 3600);
-+#endif
-+ tzinfo->daylight = curzone->tm_isdst;
-+
-+ return tzinfo;
-+}
-+
-+glong
-+tz_location_get_utc_offset (TzLocation * loc)
-+{
-+ TzInfo *tz_info;
-+ glong offset;
-+
-+ tz_info = tz_info_from_location (loc);
-+ offset = tz_info->utc_offset;
-+ tz_info_free (tz_info);
-+ return offset;
-+}
-+
-+void
-+tz_info_free (TzInfo * tzinfo)
-+{
-+ g_return_if_fail (tzinfo != NULL);
-+
-+ if (tzinfo->tzname_normal)
-+ g_free (tzinfo->tzname_normal);
-+ if (tzinfo->tzname_daylight)
-+ g_free (tzinfo->tzname_daylight);
-+ g_free (tzinfo);
-+}
-+
-+#ifdef HAVE_LINUX
-+static gboolean
-+find_from_inode (char *dir, int inode, char **filename)
-+{
-+ int num_dirent, i;
-+ struct dirent **namelist;
-+
-+ num_dirent = scandir (dir, &namelist, 0, alphasort);
-+
-+ if (num_dirent == 0)
-+ return FALSE;
-+
-+ for (i = 0; i < num_dirent; i++)
-+ {
-+ struct stat file_st;
-+
-+ if (strcmp (namelist[i]->d_name, ".") != 0 &&
-+ strcmp (namelist[i]->d_name, "..") != 0)
-+ {
-+ char path[1024];
-+
-+ sprintf (path, "%s/%s", dir, namelist[i]->d_name);
-+
-+ if (stat (path, &file_st) == 0)
-+ {
-+
-+ if (S_ISDIR (file_st.st_mode))
-+ {
-+ if (find_from_inode (path, inode, filename))
-+ {
-+ g_free (namelist);
-+ return TRUE;
-+ }
-+ }
-+ else if (inode == file_st.st_ino)
-+ {
-+ *filename = g_strdup (path);
-+ g_free (namelist);
-+ return TRUE;
-+ }
-+ }
-+ else
-+ {
-+ g_free (namelist);
-+ return FALSE;
-+ }
-+ }
-+ }
-+ g_free (namelist);
-+ return FALSE;
-+}
-+#endif
-+
-+char *
-+tz_get_system_timezone (void)
-+{
-+ struct stat st_clock, st_lt;
-+
-+ int fd, status;
-+
-+ char *tmpfilebuf, *tok_res, **toks, *file, *tz;
-+
-+ status = stat (SYS_CLOCK_FILE, &st_clock);
-+
-+ if (status == 0)
-+ {
-+ fd = open (SYS_CLOCK_FILE, O_RDONLY);
-+
-+ if (fd > 0)
-+ {
-+ tmpfilebuf = g_new (char, st_clock.st_size + 1);
-+
-+ status = read (fd, tmpfilebuf, st_clock.st_size);
-+
-+ close (fd);
-+
-+ if (status == st_clock.st_size)
-+ {
-+ tok_res = strstr (tmpfilebuf, ZONE_TOKEN);
-+
-+ if (tok_res) /* found timezone */
-+ {
-+ char *tz = NULL, **toks2;
-+#ifdef HAVE_SOLARIS
-+ toks = g_strsplit (tok_res, "\n", 3);
-+
-+ if (toks[0])
-+ {
-+ toks2 = g_strsplit (toks[0], ZONE_TOKEN, 3);
-+ }
-+ g_strfreev (toks);
-+
-+ tz = g_strdup (toks2[1]);
-+#endif
-+#ifdef HAVE_LINUX
-+ toks = g_strsplit (tok_res, "\"", 3);
-+
-+ tz = g_strdup (toks[1]);
-+ g_strfreev (toks);
-+#endif
-+ g_free (tmpfilebuf);
-+ return tz;
-+ }
-+ }
-+ }
-+ }
-+
-+
-+#ifdef HAVE_LINUX
-+ /* the SYS_CLOCK_FILE didn't contain timezone info
-+ * find the timezone from hard link LOCALTIME_FILE */
-+
-+ status = stat (LOCALTIME_FILE, &st_lt);
-+
-+ if (find_from_inode (ZONE_DIR, st_lt.st_ino, &file))
-+ {
-+ file += strlen (ZONE_DIR) + 1; /* +1 is for the / */
-+
-+ tz = g_strdup (file);
-+ g_free (file);
-+ return tz;
-+ }
-+#endif
-+ return NULL;
-+}
-+
-+
-+/* ----------------- *
-+ * Private functions *
-+ * ----------------- */
-+
-+static gchar *
-+tz_data_file_get (void)
-+{
-+ gchar *file;
-+
-+ file = g_strdup (TZ_DATA_FILE);
-+
-+ return file;
-+}
-+
-+static float
-+convert_pos (gchar * pos, int digits)
-+{
-+ gchar whole[10];
-+ gchar *fraction;
-+ gint i;
-+ float t1, t2;
-+
-+ if (!pos || strlen (pos) < 4 || digits > 9)
-+ return 0.0;
-+
-+ for (i = 0; i < digits + 1; i++)
-+ whole[i] = pos[i];
-+ whole[i] = '\0';
-+ fraction = pos + digits + 1;
-+
-+ t1 = g_strtod (whole, NULL);
-+ t2 = g_strtod (fraction, NULL);
-+
-+ if (t1 >= 0.0)
-+ return t1 + t2 / pow (10.0, strlen (fraction));
-+ else
-+ return t1 - t2 / pow (10.0, strlen (fraction));
-+}
-+
-+
-+
-+
-+static int
-+compare_country_names (const void *a, const void *b)
-+{
-+ const TzLocation *tza = *(TzLocation **) a;
-+ const TzLocation *tzb = *(TzLocation **) b;
-+
-+ return strcmp (tza->zone, tzb->zone);
-+}
-+
-+
-+static void
-+sort_locations_by_country (GPtrArray * locations)
-+{
-+ qsort (locations->pdata, locations->len, sizeof (gpointer),
-+ compare_country_names);
-+}
-+
-+TzLocation *
-+tz_get_location_by_name (TzDB *tzdb, gchar * name)
-+{
-+ TzLocation *tz_loc = NULL;
-+ GPtrArray *locs;
-+ int i;
-+
-+ locs = tz_get_locations (tzdb);
-+
-+ for (i = 0; i < locs->len; i++)
-+ {
-+ TzLocation *tz_loc_temp;
-+
-+ tz_loc_temp = g_ptr_array_index (locs, i);
-+
-+ if (tz_loc_temp
-+ && !g_utf8_collate (_(tz_location_get_zone (tz_loc_temp)), _(name)))
-+ {
-+ tz_loc = tz_loc_temp;
-+ break;
-+ }
-+ }
-+
-+ return tz_loc;
-+}
-+
-+
-diff -Nrup gnome-panel-2.14.1/applets/clock/tz.h ../gnome-panel-2.14.1/applets/clock/tz.h
---- gnome-panel-2.14.1/applets/clock/tz.h 1970-01-01 01:00:00.000000000 +0100
-+++ ../gnome-panel-2.14.1/applets/clock/tz.h 2006-06-12 16:18:42.719925000 +0200
-@@ -0,0 +1,114 @@
-+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-+/* Generic timezone utilities.
-+ *
-+ * Copyright (C) 2000-2001 Ximian, Inc.
-+ * Copyright (C) 2004 Sun Microsystems, Inc.
-+ *
-+ * Authors: Hans Petter Jansson <[email protected]>
-+ * Erwann Chenede <[email protected]>
-+ *
-+ *
-+ * Largely based on Michael Fulbright's work on Anaconda.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
-+ */
-+
-+
-+#ifndef _E_TZ_H
-+#define _E_TZ_H
-+
-+#include <glib.h>
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <unistd.h>
-+#include <time.h>
-+#include <math.h>
-+#include <string.h>
-+#include <dirent.h>
-+#include <sys/types.h>
-+#include <sys/stat.h>
-+#include <fcntl.h>
-+#include <time.h>
-+#include <config.h>
-+#include <libgnome/libgnome.h>
-+
-+#ifdef HAVE_LINUX
-+#define TZ_DATA_FILE "/usr/share/zoneinfo/zone.tab"
-+#define ZONE_TOKEN "TIMEZONE=\""
-+#define SYS_CLOCK_FILE "/etc/sysconfig/clock"
-+#endif
-+#ifdef HAVE_SOLARIS
-+#define TZ_DATA_FILE "/usr/share/lib/zoneinfo/tab/zone_sun.tab"
-+#define ZONE_TOKEN "TZ="
-+#define SYS_CLOCK_FILE "/etc/TIMEZONE"
-+#endif
-+
-+#define LOCALTIME_FILE "/etc/localtime"
-+#define ZONE_DIR "/usr/share/zoneinfo"
-+
-+typedef struct _TzDB TzDB;
-+typedef struct _TzLocation TzLocation;
-+typedef struct _TzInfo TzInfo;
-+
-+
-+struct _TzDB
-+{
-+ GPtrArray *locations;
-+};
-+
-+struct _TzLocation
-+{
-+ gchar *country;
-+ gdouble latitude;
-+ gdouble longitude;
-+ gchar *zone;
-+ gchar *comment;
-+};
-+
-+/* see the glibc info page information on time zone information */
-+/* tzname_normal is the default name for the timezone */
-+/* tzname_daylight is the name of the zone when in daylight savings */
-+/* utc_offset is offset in seconds from utc */
-+/* daylight if non-zero then location obeys daylight savings */
-+
-+struct _TzInfo
-+{
-+ gchar *tzname_normal;
-+ gchar *tzname_daylight;
-+ glong utc_offset;
-+ gint daylight;
-+};
-+
-+
-+TzDB *tz_load_db (void);
-+void tz_free_db (TzDB *tz_db);
-+GPtrArray *tz_get_locations (TzDB *db);
-+void tz_location_get_position (TzLocation *loc,
-+ double *longitude, double *latitude);
-+char *tz_location_get_country (TzLocation *loc);
-+gchar *tz_location_get_zone (TzLocation *loc);
-+gchar *tz_location_get_comment (TzLocation *loc);
-+glong tz_location_get_utc_offset (TzLocation *loc);
-+gint tz_location_set_locally (TzLocation *loc);
-+TzInfo *tz_info_from_location (TzLocation *loc);
-+void tz_info_free (TzInfo *tz_info);
-+void tz_location_free (TzLocation *loc);
-+struct tm *tz_get_localtime_at (const char *zone,
-+ const time_t *now);
-+char * tz_get_system_timezone (void);
-+TzLocation * tz_get_location_by_name (TzDB *tzdb,
-+ gchar * name);
-+#endif
-+
-diff -Nrup gnome-panel-2.14.1/config.h.in ../gnome-panel-2.14.1/config.h.in
---- gnome-panel-2.14.1/config.h.in 2006-04-10 15:46:18.000000000 +0200
-+++ ../gnome-panel-2.14.1/config.h.in 2006-06-12 16:18:40.872295000 +0200
-@@ -103,3 +103,6 @@
-
- /* Define to 1 if the X Window System is missing or not being used. */
- #undef X_DISPLAY_MISSING
-+
-+#undef HAVE_SOLARIS
-+#undef HAVE_LINUX
-diff -Nrup gnome-panel-2.14.1/configure.in ../gnome-panel-2.14.1/configure.in
---- gnome-panel-2.14.1/configure.in 2006-06-12 16:19:24.722615000 +0200
-+++ ../gnome-panel-2.14.1/configure.in 2006-06-12 16:18:40.868184000 +0200
-@@ -97,7 +97,7 @@ if test -n "$LIBECAL_REQUIREMENT"; then
- fi
- AM_CONDITIONAL(HAVE_LIBECAL, test -n "$LIBECAL_REQUIREMENT")
-
--PKG_CHECK_MODULES(CLOCK, gtk+-2.0 >= $GTK_REQUIRED libgnomeui-2.0 >= $LIBGNOMEUI_REQUIRED $LIBECAL_REQUIREMENT)
-+PKG_CHECK_MODULES(CLOCK, gtk+-2.0 >= $GTK_REQUIRED libgnomeui-2.0 >= $LIBGNOMEUI_REQUIRED $LIBECAL_REQUIREMENT libglade-2.0 >= $LIBGLADE_REQUIRED)
- AC_SUBST(CLOCK_CFLAGS)
- AC_SUBST(CLOCK_LIBS)
-
-@@ -181,6 +181,18 @@ fi
-
- AM_GCONF_SOURCE_2
-
-+dnl platform test
-+case $host in
-+*-*-solaris*)
-+ ostype=solaris
-+ AC_DEFINE(HAVE_SOLARIS, 1, [Define to 1])
-+ ;;
-+*-*-linux*)
-+ ostype=linux
-+ AC_DEFINE(HAVE_LINUX, 1, [Define to 1])
-+ ;;
-+esac
-+
- dnl Don't use AC_PROG_AWK since we need the full pathname.
- AC_PATH_PROGS(AWK, mawk gawk nawk awk, )
- AC_PATH_PROGS(PERL, perl5 perl)
-@@ -208,6 +220,7 @@ libpanel-applet/Makefile
- po/Makefile.in
- applets/Makefile
- applets/clock/Makefile
-+applets/clock/e-map/Makefile
- applets/notification_area/Makefile
- applets/wncklet/Makefile
- doc/Makefile
---- gnome-panel-2.16.1.old/applets/clock/Makefile.am 2006-10-20 10:31:42.149737000 +0100
-+++ gnome-panel-2.16.1/applets/clock/Makefile.am 2006-10-20 10:36:13.637552000 +0100
-@@ -1,3 +1,5 @@
-+SUBDIRS = e-map
-+
- INCLUDES = \
- -I$(srcdir)/../../libpanel-applet \
- -I$(top_builddir)/libpanel-applet \
-@@ -6,6 +8,7 @@
- $(WARN_CFLAGS) \
- $(CLOCK_CFLAGS) \
- -DDATADIR=\""$(datadir)"\" \
-+ -DGLADEDIR=\""$(datadir)/gnome/panel/glade"\" \
- -DLIBDIR=\""$(libdir)"\" \
- -DSYSCONFDIR=\""$(sysconfdir)"\" \
- -DPREFIX=\""$(prefix)"\" \
-@@ -20,10 +23,17 @@
- calendar-debug.h
- endif
-
--CLOCK_SOURCES = clock.c $(CALENDAR_SOURCES)
-+CLOCK_SOURCES = clock.c \
-+ $(CALENDAR_SOURCES) \
-+ tz.h \
-+ tz.c \
-+ clock.h \
-+ timezone-selection.c \
-+ multi-timezone.c
-
- CLOCK_LDADD = \
- ../../libpanel-applet/libpanel-applet-2.la \
-+ e-map/libemap.a \
- $(CLOCK_LIBS)
-
- if CLOCK_INPROCESS
-@@ -46,6 +56,9 @@
- clock_applet_CFLAGS =
- endif
-
-+gladedir = $(datadir)/gnome/panel/glade
-+glade_DATA = timezone.glade
-+
- uidir = $(datadir)/gnome-2.0/ui
- ui_DATA = GNOME_ClockApplet.xml
-
---- gnome-panel-2.16.1.old/icons/Makefile.am 2006-10-20 10:31:41.032555000 +0100
-+++ gnome-panel-2.16.1/icons/Makefile.am 2006-10-20 10:38:48.656881000 +0100
-@@ -6,6 +6,7 @@
- gegl_DATA = \
- gnome-gegl2-2.png \
- gnome-gegl2.png \
-+ world_map-960.png \
- $(NULL)
-
- EXTRA_DIST = $(gegl_DATA)
---- gnome-panel-2.16.1.old/applets/clock/clock.c 2006-10-20 10:31:42.188005000 +0100
-+++ gnome-panel-2.16.1/applets/clock/clock.c 2006-10-20 11:26:43.521255000 +0100
-@@ -27,6 +27,7 @@
- * George Lebl
- * Gediminas Paulauskas
- * Mark McLoughlin
-+ * Erwann Chenede
- */
-
- /*
-@@ -41,34 +42,9 @@
-
- #include "config.h"
-
--#include <stdio.h>
--#include <sys/stat.h>
--#include <unistd.h>
--#include <dirent.h>
--#include <string.h>
--#include <time.h>
--#include <langinfo.h>
--
--#include <panel-applet.h>
--#include <panel-applet-gconf.h>
--
--#include <gtk/gtk.h>
--#include <gdk/gdkkeysyms.h>
--#include <gconf/gconf-client.h>
--#include <libgnomeui/gnome-help.h>
--#include <libgnomeui/gnome-url.h>
--
--#ifdef HAVE_LIBECAL
--#include "calendar-client.h"
--#endif
-+#include "clock.h"
-
- #define CLOCK_ICON "gnome-panel-clock"
--#define INTERNETSECOND (864)
--#define INTERNETBEAT (86400)
--
--#define N_GCONF_PREFS 7
--
--#define NEVER_SENSITIVE "never_sensitive"
-
- static const char* KEY_FORMAT = "format";
- static const char* KEY_SHOW_SECONDS = "show_seconds";
-@@ -77,6 +53,7 @@
- static const char* KEY_CONFIG_TOOL = "config_tool";
- static const char* KEY_CUSTOM_FORMAT = "custom_format";
- static const char* KEY_SHOW_WEEK = "show_week_numbers";
-+static const char* KEY_SHOW_ZONES = "show_zones";
-
- static const char *clock_config_tools [] = {
- "system-config-date",
-@@ -85,16 +62,6 @@
- "time-admin",
- };
-
--/* Needs to match the indices in the combo */
--typedef enum {
-- CLOCK_FORMAT_INVALID = 0,
-- CLOCK_FORMAT_12,
-- CLOCK_FORMAT_24,
-- CLOCK_FORMAT_UNIX,
-- CLOCK_FORMAT_INTERNET,
-- CLOCK_FORMAT_CUSTOM
--} ClockFormat;
--
- static GConfEnumStringPair format_type_enum_map [] = {
- { CLOCK_FORMAT_12, "12-hour" },
- { CLOCK_FORMAT_24, "24-hour" },
-@@ -104,63 +71,6 @@
- { 0, NULL }
- };
-
--typedef struct _ClockData ClockData;
--
--struct _ClockData {
-- /* widgets */
-- GtkWidget *applet;
-- GtkWidget *clockw;
-- GtkWidget *toggle;
-- GtkWidget *props;
-- GtkWidget *about;
-- GtkWidget *calendar_popup;
-- GtkWidget *calendar;
--
--#ifdef HAVE_LIBECAL
-- GtkWidget *task_list;
-- GtkWidget *appointment_list;
--
-- GtkListStore *appointments_model;
-- GtkListStore *tasks_model;
-- GtkTreeModelFilter *tasks_filter;
--
-- CalendarClient *client;
--#endif /* HAVE_LIBECAL */
--
-- /* preferences */
-- ClockFormat format;
-- char *custom_format;
-- gboolean showseconds;
-- gboolean showdate;
-- gboolean gmt_time;
-- gboolean showweek;
--
-- char *config_tool;
--
-- /* runtime data */
-- time_t current_time;
-- char *timeformat;
-- guint timeout;
-- PanelAppletOrient orient;
-- int size;
-- GtkAllocation old_allocation;
--
-- int fixed_width;
-- int fixed_height;
--
-- GtkWidget *showseconds_check;
-- GtkWidget *showdate_check;
-- GtkWidget *gmt_time_check;
-- GtkWidget *custom_hbox;
-- GtkWidget *custom_label;
-- GtkWidget *custom_entry;
-- gboolean custom_format_shown;
--
-- gboolean can_handle_format_12;
--
-- guint listeners [N_GCONF_PREFS];
--};
--
- static void update_clock (ClockData * cd);
- static float get_itime (time_t current_time);
-
-@@ -218,8 +128,8 @@
- return width;
- }
-
--static void
--set_tooltip (GtkWidget *applet,
-+void
-+clock_set_tooltip (GtkWidget *applet,
- GtkWidget *widget,
- const char *tip)
- {
-@@ -445,6 +355,31 @@
- update_orient (cd);
- gtk_widget_queue_resize (cd->toggle);
-
-+ /* multi timezone part */
-+
-+ if (cd->multizone_popup && cd->tip_list && GTK_WIDGET_MAPPED (cd->multizone_popup)) {
-+ GSList *tmp_list;
-+ char timeformat [128];
-+ char *cr;
-+
-+ g_stpcpy (timeformat, cd->timeformat);
-+ cr = g_strrstr (timeformat, "\n");
-+ if (cr)
-+ *cr = ' ';
-+
-+ for (tmp_list = cd->tip_list; tmp_list ; tmp_list = tmp_list->next) {
-+ char tip_hour[256];
-+ TipZone *tip_zone = tmp_list->data;
-+
-+ tm = tz_get_localtime_at (tip_zone->zone, &cd->current_time);
-+
-+ if (strftime (tip_hour, sizeof (tip_hour), timeformat, tm) <= 0)
-+ strcpy (tip_hour, "???");
-+
-+ gtk_label_set_text (GTK_LABEL (tip_zone->time_label),
-+ g_locale_to_utf8 (tip_hour, -1, NULL, NULL, NULL));
-+ }
-+
- if (!cd->showdate) {
- /* Show date in tooltip */
- loc = g_locale_from_utf8 (_("%A %B %d"), -1, NULL, NULL, NULL);
-@@ -455,13 +390,13 @@
- g_free (loc);
-
- utf8 = g_locale_to_utf8 (date, -1, NULL, NULL, NULL);
-- set_tooltip (cd->applet, cd->toggle, utf8);
-- g_free (utf8);
-+ clock_set_tooltip (cd->applet, cd->toggle, utf8);
-+ }
- } else {
- #ifdef HAVE_LIBECAL
-- set_tooltip (cd->applet, cd->toggle, _("Click to view your appointments and tasks"));
-+ clock_set_tooltip (cd->applet, cd->toggle, _("Click to view your appointments and tasks"));
- #else
-- set_tooltip (cd->applet, cd->toggle, _("Click to view month calendar"));
-+ clock_set_tooltip (cd->applet, cd->toggle, _("Click to view month calendar"));
- #endif
- }
- }
-@@ -545,6 +480,14 @@
- gtk_widget_destroy (cd->calendar_popup);
- cd->calendar_popup = NULL;
-
-+ if (cd->multizone_popup)
-+ gtk_widget_destroy (cd->multizone_popup);
-+ cd->multizone_popup = NULL;
-+
-+ if (cd->timezone_dialog)
-+ gtk_widget_destroy (cd->timezone_dialog);
-+ cd->timezone_dialog = NULL;
-+
- g_free (cd->timeformat);
- g_free (cd->config_tool);
- g_free (cd->custom_format);
-@@ -1599,12 +1542,46 @@
- }
-
- static void
-+pop_timezones (ClockData *cd)
-+{
-+ GtkWidget *button = cd->multizone_toggle;
-+
-+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button))) {
-+ GtkWidget *calendar = g_object_get_data (G_OBJECT (button), "calendar");
-+
-+ if (!cd->multizone_popup) {
-+ cd->multizone_popup = create_multi_timezones_popup (cd, gtk_widget_get_screen (cd->applet));
-+ }
-+
-+ refresh_clock (cd);
-+ gtk_widget_show_all (cd->multizone_popup);
-+
-+ if (calendar) {
-+ gtk_widget_hide (calendar);
-+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cd->toggle), FALSE);
-+ }
-+
-+ present_calendar_popup (cd, cd->multizone_popup, button);
-+ } else {
-+ if (cd->multizone_popup)
-+ gtk_widget_hide (cd->multizone_popup);
-+ }
-+
-+ update_clock (cd);
-+}
-+
-+static void
- update_popup (ClockData *cd)
- {
-+ GtkWindow *window;
-+
-+ window = g_object_get_data (G_OBJECT (cd->toggle), "calendar");
-+
- if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (cd->toggle))) {
- if (cd->calendar_popup)
- gtk_widget_destroy (cd->calendar_popup);
- cd->calendar_popup = NULL;
-+ g_object_set_data (G_OBJECT (cd->toggle), "calendar", NULL);
- return;
- }
-
-@@ -1612,9 +1589,14 @@
- cd->calendar_popup = create_calendar (cd, gtk_widget_get_screen (cd->applet));
- g_object_add_weak_pointer (G_OBJECT (cd->calendar_popup),
- (gpointer *) &cd->calendar_popup);
-+ g_object_set_data (G_OBJECT (cd->toggle), "calendar", cd->calendar_popup);
- }
-
- if (cd->calendar_popup && GTK_WIDGET_REALIZED (cd->toggle)) {
-+ if (cd->multizone_popup) {
-+ gtk_widget_hide (cd->multizone_popup);
-+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cd->multizone_toggle), FALSE);
-+ }
- #ifdef HAVE_LIBECAL
- if (cd->tasks_filter && cd->task_list)
- gtk_tree_model_filter_refilter (cd->tasks_filter);
-@@ -1626,6 +1608,12 @@
- }
-
- static void
-+toggle_timezone (GtkWidget *button, ClockData *cd)
-+{
-+ pop_timezones (cd);
-+}
-+
-+static void
- toggle_calendar (GtkWidget *button,
- ClockData *cd)
- {
-@@ -1681,12 +1669,93 @@
- }
-
- static void
-+change_clock_orientation (ClockData *cd)
-+{
-+ GtkWidget *box;
-+
-+ switch (cd->orient) {
-+ case PANEL_APPLET_ORIENT_RIGHT:
-+ case PANEL_APPLET_ORIENT_LEFT:
-+ box = gtk_vbox_new (FALSE, 1);
-+ break;
-+ case PANEL_APPLET_ORIENT_DOWN:
-+ case PANEL_APPLET_ORIENT_UP:
-+ box = gtk_hbox_new (FALSE, 1);
-+ break;
-+ }
-+
-+ if (cd->hbox) {
-+ gtk_widget_reparent (cd->multizone_toggle, box);
-+ gtk_widget_reparent (cd->toggle, box);
-+ gtk_container_remove (GTK_CONTAINER (cd->applet), cd->hbox);
-+ } else {
-+ gtk_container_add (GTK_CONTAINER (box), cd->multizone_toggle);
-+ gtk_container_add (GTK_CONTAINER (box), cd->toggle);
-+ }
-+
-+ cd->hbox = box;
-+ gtk_container_add (GTK_CONTAINER (cd->applet), box);
-+ gtk_widget_show_all (box);
-+
-+ if (!cd->show_multiple_timezones)
-+ gtk_widget_hide (cd->multizone_toggle);
-+}
-+
-+
-+static void
-+multizone_scale_image (GtkWidget *widget,
-+ GtkAllocation *allocation,
-+ ClockData *cd)
-+{
-+#define TOGGLE_BUTTON_BORDER 10
-+ GdkPixbuf *pb;
-+ int w, h, new_w, new_h;
-+ gboolean need_to_scale = FALSE;
-+ w = gdk_pixbuf_get_width (cd->image);
-+ h = gdk_pixbuf_get_height (cd->image);
-+
-+ switch (cd->orient) {
-+ case PANEL_APPLET_ORIENT_UP:
-+ case PANEL_APPLET_ORIENT_DOWN:
-+
-+ if (cd->save_allocation_h != allocation->height) {
-+ cd->save_allocation_h = allocation->height;
-+ new_h = allocation->height - TOGGLE_BUTTON_BORDER;
-+ new_w = (w * new_h) / h;
-+ need_to_scale = TRUE;
-+ }
-+ break;
-+ case PANEL_APPLET_ORIENT_RIGHT:
-+ case PANEL_APPLET_ORIENT_LEFT:
-+ if (cd->save_allocation_w != allocation->width) {
-+ cd->save_allocation_w = allocation->width;
-+ new_w = allocation->width - TOGGLE_BUTTON_BORDER;
-+ new_h = (h * new_w) /w ;
-+ need_to_scale = TRUE;
-+ }
-+ break;
-+ }
-+
-+ if (need_to_scale) {
-+ if (new_h < TOGGLE_BUTTON_BORDER)
-+ new_h = TOGGLE_BUTTON_BORDER;
-+ if (new_w < TOGGLE_BUTTON_BORDER)
-+ new_w = TOGGLE_BUTTON_BORDER;
-+
-+ pb = gdk_pixbuf_scale_simple (cd->image, new_w, new_h, GDK_INTERP_HYPER);
-+ gtk_image_set_from_pixbuf (GTK_IMAGE (cd->multizone_image), pb);
-+ }
-+}
-+
-+static void
- create_clock_widget (ClockData *cd)
- {
- GtkWidget *clock;
- GtkWidget *toggle;
- GtkWidget *alignment;
-+ GtkIconInfo *icon_info;
-
-+ cd->orient = panel_applet_get_orient (PANEL_APPLET (cd->applet));
- clock = gtk_label_new ("hmm?");
- g_signal_connect (clock, "size_request",
- G_CALLBACK (clock_size_request),
-@@ -1721,16 +1790,38 @@
-
- cd->clockw = clock;
-
-- cd->props = NULL;
-+ cd->size = panel_applet_get_size (PANEL_APPLET (cd->applet));
-
-- cd->orient = panel_applet_get_orient (PANEL_APPLET (cd->applet));
-+ cd->multizone_toggle = gtk_toggle_button_new ();
-+ gtk_container_set_resize_mode (GTK_CONTAINER (cd->multizone_toggle),
-+ GTK_RESIZE_IMMEDIATE);
-+ gtk_button_set_relief (GTK_BUTTON (cd->multizone_toggle), GTK_RELIEF_NONE);
-+
-+ icon_info = gtk_icon_theme_lookup_icon (gtk_icon_theme_get_default (), "stock_timezone", 48, 0);
-+ cd->image = gtk_icon_info_load_icon (icon_info, NULL);
-+ cd->multizone_image = gtk_image_new_from_pixbuf (cd->image);
-+ gtk_icon_info_free (icon_info);
-+ gtk_widget_show (cd->multizone_image);
-+
-+ gtk_container_add (GTK_CONTAINER (cd->multizone_toggle), cd->multizone_image);
-+ gtk_widget_show (cd->multizone_toggle);
-+
-+ change_clock_orientation (cd);
-+ cd->save_allocation_h = 0;
-+ cd->save_allocation_w = 0;
-
-- cd->size = panel_applet_get_size (PANEL_APPLET (cd->applet));
-+ cd->props = NULL;
-
- g_signal_connect (G_OBJECT(clock), "destroy",
- G_CALLBACK (destroy_clock),
- cd);
-
-+ g_signal_connect (cd->multizone_toggle, "toggled",
-+ G_CALLBACK (toggle_timezone), cd);
-+
-+ g_signal_connect (cd->multizone_toggle, "size-allocate",
-+ G_CALLBACK (multizone_scale_image), cd);
-+
- set_atk_name_description (GTK_WIDGET (cd->applet), NULL,
- _("Computer Clock"));
-
-@@ -1779,6 +1870,7 @@
- unfix_size (cd);
- update_clock (cd);
- update_popup (cd);
-+ change_clock_orientation (cd);
- }
-
- /* this is when the panel size changes */
-@@ -1789,12 +1881,12 @@
- {
- int new_size;
-
-- if (cd->old_allocation.width == allocation->width &&
-- cd->old_allocation.height == allocation->height)
-+ if (cd->save_allocation_w == allocation->width &&
-+ cd->save_allocation_h == allocation->height)
- return;
-
-- cd->old_allocation.width = allocation->width;
-- cd->old_allocation.height = allocation->height;
-+ cd->save_allocation_w = allocation->width;
-+ cd->save_allocation_h = allocation->height;
-
- if (cd->orient == PANEL_APPLET_ORIENT_LEFT ||
- cd->orient == PANEL_APPLET_ORIENT_RIGHT)
-@@ -2176,6 +2268,29 @@
- }
-
- static void
-+show_multi_zones_changed (GConfClient *client,
-+ guint cnxn_id,
-+ GConfEntry *entry,
-+ ClockData *clock)
-+{
-+ gboolean value;
-+
-+ if (!entry->value || entry->value->type != GCONF_VALUE_BOOL)
-+ return;
-+
-+ value = gconf_value_get_bool (entry->value);
-+
-+ clock->show_multiple_timezones = (value != 0);
-+
-+ if (clock->show_multiple_timezones)
-+ gtk_widget_show (clock->multizone_toggle);
-+ else
-+ gtk_widget_hide (clock->multizone_toggle);
-+
-+ refresh_clock (clock);
-+}
-+
-+static void
- setup_gconf (ClockData *clock)
- {
- GConfClient *client;
-@@ -2246,6 +2361,15 @@
- clock, NULL, NULL);
- g_free (key);
-
-+ key = panel_applet_gconf_get_full_key (PANEL_APPLET (clock->applet),
-+ KEY_SHOW_ZONES);
-+ clock->listeners [7] =
-+ gconf_client_notify_add (
-+ client, key,
-+ (GConfClientNotifyFunc) show_multi_zones_changed,
-+ clock, NULL, NULL);
-+ g_free (key);
-+
- g_object_unref (G_OBJECT (client));
- }
-
-@@ -2342,10 +2466,8 @@
-
- create_clock_widget (cd);
-
-- gtk_container_set_border_width (GTK_CONTAINER (cd->applet), 0);
-- gtk_container_set_border_width (GTK_CONTAINER (cd->toggle), 0);
-- gtk_container_add (GTK_CONTAINER (cd->applet), cd->toggle);
--
-+ cd->show_multiple_timezones = panel_applet_gconf_get_bool (applet, KEY_SHOW_ZONES, NULL);
-+
- #ifndef CLOCK_INPROCESS
- gtk_window_set_default_icon_name (CLOCK_ICON);
- #endif
-@@ -2519,6 +2641,16 @@
- }
-
- static void
-+set_show_zones_cb (GtkWidget *w,
-+ ClockData *clock)
-+{
-+ panel_applet_gconf_set_bool (PANEL_APPLET (clock->applet),
-+ KEY_SHOW_ZONES,
-+ GTK_TOGGLE_BUTTON (w)->active,
-+ NULL);
-+}
-+
-+static void
- set_show_seconds_cb (GtkWidget *w,
- ClockData *clock)
- {
-@@ -2709,6 +2841,15 @@
- cd);
- gtk_widget_show (cd->gmt_time_check);
-
-+ cd->showzones_check = gtk_check_button_new_with_mnemonic (_("Show _time zones button"));
-+ gtk_box_pack_start (GTK_BOX (vbox), cd->showzones_check, FALSE, FALSE, 0);
-+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cd->showzones_check),
-+ cd->show_multiple_timezones);
-+ g_signal_connect (G_OBJECT (cd->showzones_check), "toggled",
-+ G_CALLBACK (set_show_zones_cb),
-+ cd);
-+ gtk_widget_show (cd->showzones_check);
-+
- g_signal_connect (cd->props, "destroy",
- G_CALLBACK (gtk_widget_destroyed),
- &cd->props);
-@@ -2781,6 +2922,7 @@
- {
- "George Lebl <[email protected]>",
- "Gediminas Paulauskas <[email protected]>",
-+ "multi time zone Erwann Chenede",
- NULL
- };
- static const char *documenters[] =
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/gnome-panel-11-trusted-extensions.diff Fri Oct 20 15:31:04 2006 +0000
@@ -0,0 +1,799 @@
+diff -urN gnome-panel-2.14.1/applets/wncklet/GNOME_WorkspaceSwitcherApplet.xml ../SUNWgnome-panel-2.14.1.hacked/gnome-panel-2.14.1/applets/wncklet/GNOME_WorkspaceSwitcherApplet.xml
+--- gnome-panel-2.14.1/applets/wncklet/GNOME_WorkspaceSwitcherApplet.xml 2004-06-11 11:53:17.000000000 +0100
++++ ../SUNWgnome-panel-2.14.1.hacked/gnome-panel-2.14.1/applets/wncklet/GNOME_WorkspaceSwitcherApplet.xml 2006-06-09 12:48:59.580890000 +0100
+@@ -1,6 +1,8 @@
+ <Root>
+ <popups>
+ <popup name="button3">
++ <menuitem name="Workspace Label Item" verb="ChangeWorkspaceLabel" _label="_Change Workspace Label..."/>
++ <separator/>
+ <menuitem name="Pager Preferences Item" verb="PagerPreferences" _label="_Preferences"
+ pixtype="stock" pixname="gtk-properties"/>
+ <menuitem name="Pager Help Item" verb="PagerHelp" _label="_Help"
+diff -urN gnome-panel-2.14.1/applets/wncklet/wnck-tsol.c ../SUNWgnome-panel-2.14.1.hacked/gnome-panel-2.14.1/applets/wncklet/wnck-tsol.c
+--- gnome-panel-2.14.1/applets/wncklet/wnck-tsol.c 1970-01-01 01:00:00.000000000 +0100
++++ ../SUNWgnome-panel-2.14.1.hacked/gnome-panel-2.14.1/applets/wncklet/wnck-tsol.c 2006-06-09 16:31:40.489536000 +0100
+@@ -0,0 +1,217 @@
++#include <config.h>
++#ifdef HAVE_LIBGNOMETSOL
++
++#include <stdlib.h>
++#include <string.h>
++#include <dlfcn.h>
++#include <link.h>
++#include <glib.h>
++#include <panel-applet.h>
++#include "wnck-tsol.h"
++#define WNCK_I_KNOW_THIS_IS_UNSTABLE
++#include <libwnck/libwnck.h>
++
++static
++void * dlopen_tsol (void)
++{
++ void *handle = NULL;
++
++ /*
++ * No 64-bit version of libwnck so we can get away with hardcoding
++ * to a single path on this occasion
++ */
++ if ((handle = dlopen ("/usr/lib/libtsol.so.2", RTLD_LAZY)) != NULL)
++ return handle;
++
++ return handle;
++}
++
++static
++void * dlopen_xtsol (void)
++{
++ void *handle = NULL;
++
++ if ((handle = dlopen ("/usr/lib/libXtsol.so.1", RTLD_LAZY)) != NULL)
++ return handle;
++ if ((handle = dlopen ("/usr/openwin/lib/libXtsol.so.1", RTLD_LAZY)) != NULL)
++ return handle;
++
++ return handle;
++}
++
++static
++void * dlopen_gnometsol (void)
++{
++ void *handle = NULL;
++
++ if ((handle = dlopen ("/usr/lib/libgnometsol.so", RTLD_LAZY)) != NULL)
++ return handle;
++
++ return handle;
++}
++
++
++gboolean
++_wnck_use_trusted_extensions (void)
++{
++ static int trusted = -1;
++
++ /*
++ * Sun Trusted Extensions (tm) for Solaris (tm) support. (Damn I should be a lawyer).
++ *
++ * It is necessary to use dlopen because the label aware extensions to libwnck work
++ * only on systems with the trusted extensions installed and with the SUN_TSOL
++ * xserver extension present
++ */
++
++ if (trusted < 0) {
++ static gpointer tsol_handle = NULL;
++ static gpointer xtsol_handle = NULL;
++ static gpointer gnometsol_handle = NULL;
++
++ if (getenv ("TRUSTED_SESSION") == NULL) {
++ trusted = 0;
++ return 0;
++ }
++
++ tsol_handle = dlopen_tsol ();
++ if (tsol_handle != NULL)
++ xtsol_handle = dlopen_xtsol ();
++ if (tsol_handle && xtsol_handle) {
++
++ /* libtsol functions */
++ libtsol_blequal = (tsol_blequal) dlsym (tsol_handle, "blequal");
++ libtsol_label_to_str = (tsol_label_to_str) dlsym (tsol_handle, "label_to_str");
++ libtsol_str_to_label = (tsol_str_to_label) dlsym (tsol_handle, "str_to_label");
++ libtsol_m_label_dup = (tsol_m_label_dup) dlsym (tsol_handle, "m_label_dup");
++ libtsol_m_label_free = (tsol_m_label_free) dlsym (tsol_handle, "m_label_free");
++
++ /* Other misc. libtsol functions */
++ libtsol_blminimum = (tsol_blminimum) dlsym (tsol_handle, "blminimum");
++ libtsol_blmaximum = (tsol_blmaximum) dlsym (tsol_handle, "blmaximum");
++ libtsol_blinrange = (tsol_blinrange) dlsym (tsol_handle, "blinrange");
++ libtsol_getuserrange = (tsol_getuserrange) dlsym (tsol_handle, "getuserrange");
++ libtsol_blabel_alloc = (tsol_blabel_alloc) dlsym (tsol_handle, "blabel_alloc");
++ libtsol_blabel_free = (tsol_blabel_free) dlsym (tsol_handle, "blabel_free");
++ libtsol_bsllow = (tsol_bsllow) dlsym (tsol_handle, "bsllow");
++ libtsol_bslhigh = (tsol_bslhigh) dlsym (tsol_handle, "bslhigh");
++
++ /* libXtsol functions */
++ libxtsol_XTSOLgetClientLabel = (xtsol_XTSOLgetClientLabel) dlsym (xtsol_handle,
++ "XTSOLgetClientLabel");
++ libxtsol_XTSOLIsWindowTrusted = (xtsol_XTSOLIsWindowTrusted) dlsym (xtsol_handle,
++ "XTSOLIsWindowTrusted");
++
++ if (libtsol_label_to_str == NULL ||
++ libtsol_str_to_label == NULL ||
++ libtsol_m_label_dup == NULL ||
++ libtsol_m_label_free == NULL ||
++ libtsol_blminimum == NULL ||
++ libtsol_blmaximum == NULL ||
++ libtsol_blinrange == NULL ||
++ libtsol_getuserrange == NULL ||
++ libtsol_blabel_alloc == NULL ||
++ libtsol_blabel_free == NULL ||
++ libtsol_bsllow == NULL ||
++ libtsol_bslhigh == NULL ||
++ libxtsol_XTSOLgetClientLabel == NULL ||
++ libxtsol_XTSOLIsWindowTrusted == NULL) {
++ dlclose (tsol_handle);
++ dlclose (xtsol_handle);
++ tsol_handle = NULL;
++ xtsol_handle = NULL;
++ }
++ }
++ gnometsol_handle = dlopen_gnometsol ();
++ if (gnometsol_handle != NULL) {
++ libgnometsol_gnome_label_builder_new =
++ (gnometsol_gnome_label_builder_new) dlsym (gnometsol_handle,
++ "gnome_label_builder_new");
++ libgnometsol_gnome_label_builder_get_type =
++ (gnometsol_gnome_label_builder_get_type) dlsym (gnometsol_handle,
++ "gnome_label_builder_get_type");
++ if (libgnometsol_gnome_label_builder_new == NULL ||
++ libgnometsol_gnome_label_builder_get_type == NULL)
++ gnometsol_handle = NULL;
++ }
++ trusted = ((tsol_handle != NULL) && (xtsol_handle != NULL) && (gnometsol_handle != NULL)) ? 1 : 0;
++ }
++ return trusted ? TRUE : FALSE;
++}
++
++const char *
++_wnck_get_min_label ()
++{
++ static char *min_label = NULL;
++
++ if (!min_label) {
++ min_label = (char *) getenv ("USER_MIN_SL");
++ }
++ return min_label;
++}
++
++const char*
++_wnck_get_max_label()
++{
++ static char *max_label = NULL;
++
++ if (!max_label) {
++ max_label = (char *) getenv ("USER_MAX_SL");
++ }
++ return max_label;
++}
++
++
++/* window selector part */
++
++static gboolean tsol_win_selector_label_expose_event (GtkWidget *widget,
++ GdkEventExpose *event,
++ gpointer data)
++{
++ WnckWindow *window = (WnckWindow *) data;
++
++ GdkGC *tmp_gc = gdk_gc_new (widget->window);
++ gdk_gc_set_rgb_fg_color (tmp_gc, wnck_window_get_label_color (window));
++
++ gdk_draw_rectangle (widget->window,
++ widget->style->black_gc,
++ FALSE,
++ event->area.x, event->area.y,
++ event->area.width - 1, event->area.height - 1);
++
++ gdk_draw_rectangle (widget->window,
++ tmp_gc,
++ TRUE,
++ event->area.x + 1, event->area.y + 1,
++ event->area.width - 2, event->area.height - 2);
++
++ g_object_unref (tmp_gc);
++
++ return FALSE;
++}
++
++GtkWidget *
++window_menu_create_label_indicator (WnckWindow *window,
++ GtkWidget *image)
++{
++ GtkWidget *da, *hbox;
++ da = gtk_drawing_area_new ();
++
++ g_signal_connect (G_OBJECT (da), "expose_event",
++ G_CALLBACK (tsol_win_selector_label_expose_event),
++ window);
++
++ gtk_widget_set_size_request (da, 5, -1);
++
++ hbox = gtk_hbox_new (FALSE, 4);
++
++ gtk_container_add (GTK_CONTAINER (hbox), da);
++ gtk_container_add (GTK_CONTAINER (hbox), image);
++
++ gtk_widget_show (da);
++ gtk_widget_show (hbox);
++ gtk_widget_show (image);
++
++ return hbox;
++}
++#endif /* HAVE_LIBGNOMETSOL */
+diff -urN gnome-panel-2.14.1/applets/wncklet/wnck-tsol.h ../SUNWgnome-panel-2.14.1.hacked/gnome-panel-2.14.1/applets/wncklet/wnck-tsol.h
+--- gnome-panel-2.14.1/applets/wncklet/wnck-tsol.h 1970-01-01 01:00:00.000000000 +0100
++++ ../SUNWgnome-panel-2.14.1.hacked/gnome-panel-2.14.1/applets/wncklet/wnck-tsol.h 2006-06-09 16:31:40.489611000 +0100
+@@ -0,0 +1,83 @@
++#ifndef __WNCK_TSOL_H__
++#define __WNCK_TSOL_H__
++
++#include <config.h>
++
++#ifdef HAVE_LIBGNOMETSOL
++#include <glib-2.0/glib.h>
++#include <panel-applet.h>
++#include <tsol/label.h>
++#include <sys/tsol/label_macro.h>
++#include <X11/Xlib.h>
++#include <X11/extensions/Xtsol.h>
++#include <libgnometsol/label_builder.h>
++#define WNCK_I_KNOW_THIS_IS_UNSTABLE
++#include <libwnck/libwnck.h>
++
++/* Libtsol functions */
++
++typedef int (*tsol_blequal) (const m_label_t *label1, const m_label_t *label2);
++typedef int (*tsol_label_to_str) (const m_label_t *label, char **string,
++ const m_label_str_t conversion_type,
++ uint_t flags);
++typedef int (*tsol_str_to_label) (const char *string, m_label_t **label,
++ const m_label_type_t label_type, uint_t flags,
++ int *error);
++typedef void (*tsol_m_label_dup) (m_label_t **dst, const m_label_t *src);
++typedef void (*tsol_m_label_free) (m_label_t *label);
++
++/* Other misc. libtsol functions that seem to be stable */
++typedef blrange_t* (*tsol_getuserrange) (const char *username);
++typedef int (*tsol_blinrange) (const m_label_t *label,
++ const blrange_t *range);
++typedef void (*tsol_blminimum) (m_label_t *minimum_label,
++ const m_label_t *bounding_label);
++typedef void (*tsol_blmaximum) (m_label_t *maximum_label,
++ const m_label_t *bounding_label);
++typedef m_label_t* (*tsol_blabel_alloc) (void);
++typedef void (*tsol_blabel_free) (m_label_t *label_p);
++typedef void (*tsol_bsllow) (m_label_t *label);
++typedef void (*tsol_bslhigh) (m_label_t *label);
++
++/* libXtsol functions */
++typedef Status (*xtsol_XTSOLgetClientLabel) (Display *dpy, XID xid,
++ bslabel_t *sl);
++typedef Bool (*xtsol_XTSOLIsWindowTrusted) (Display *dpy, Window win);
++
++extern gboolean _trusted_extensions_initialised;
++
++/* libgnometsol functions */
++typedef GtkWidget* (*gnometsol_gnome_label_builder_new) (char *msg,
++ blevel_t *upper, blevel_t *lower, int mode);
++typedef GType (*gnometsol_gnome_label_builder_get_type) (void);
++
++/* libtsol functions */
++tsol_blequal libtsol_blequal;
++tsol_label_to_str libtsol_label_to_str;
++tsol_str_to_label libtsol_str_to_label;
++tsol_m_label_dup libtsol_m_label_dup;
++tsol_m_label_free libtsol_m_label_free;
++/* Other misc. libtsol functions */
++tsol_blminimum libtsol_blminimum;
++tsol_blmaximum libtsol_blmaximum;
++tsol_blinrange libtsol_blinrange;
++tsol_getuserrange libtsol_getuserrange;
++tsol_blabel_alloc libtsol_blabel_alloc;
++tsol_blabel_free libtsol_blabel_free;
++tsol_bsllow libtsol_bsllow;
++tsol_bslhigh libtsol_bslhigh;
++
++xtsol_XTSOLgetClientLabel libxtsol_XTSOLgetClientLabel;
++xtsol_XTSOLIsWindowTrusted libxtsol_XTSOLIsWindowTrusted;
++
++gnometsol_gnome_label_builder_new libgnometsol_gnome_label_builder_new;
++gnometsol_gnome_label_builder_get_type libgnometsol_gnome_label_builder_get_type;
++
++gboolean _wnck_use_trusted_extensions ();
++const char* _wnck_get_min_label ();
++const char* _wnck_get_max_label ();
++
++GtkWidget* window_menu_create_label_indicator (WnckWindow *window,
++ GtkWidget *image);
++#endif /* HAVE_LIBGNOMETSOL */
++#endif
+diff -urN gnome-panel-2.14.1/applets/wncklet/workspace-switcher.c ../SUNWgnome-panel-2.14.1.hacked/gnome-panel-2.14.1/applets/wncklet/workspace-switcher.c
+--- gnome-panel-2.14.1/applets/wncklet/workspace-switcher.c 2006-03-06 21:41:15.000000000 +0000
++++ ../SUNWgnome-panel-2.14.1.hacked/gnome-panel-2.14.1/applets/wncklet/workspace-switcher.c 2006-06-09 16:40:30.737645000 +0100
+@@ -27,6 +27,10 @@
+ #include <gconf/gconf-client.h>
+ #include <libgnomeui/gnome-help.h>
+
++#ifdef HAVE_LIBGNOMETSOL
++#include "wnck-tsol.h"
++#endif
++
+ #include "workspace-switcher.h"
+
+ #include "wncklet.h"
+@@ -39,6 +43,8 @@
+ #define NUM_WORKSPACES "/apps/metacity/general/num_workspaces"
+ #define WORKSPACE_NAME "/apps/metacity/workspace_names/name_1"
+
++gboolean ugly_showing_lbuilder_global_which_sucks_fix_me = FALSE;
++
+ typedef struct {
+ GtkWidget *applet;
+
+@@ -68,6 +74,18 @@
+ guint listeners [3];
+ } PagerData;
+
++#ifdef HAVE_LIBGNOMETSOL
++static void tsol_workspace_created (WnckScreen *screen,
++ WnckWorkspace *workspace,
++ gpointer data);
++static void role_changed (WnckWorkspace *workspace,
++ gpointer data);
++static void changed_workspace (WnckScreen *screen,
++ gpointer data);
++static void workspace_label_dialog (BonoboUIComponent *uic,
++ PagerData *pager,
++ const gchar *verbname);
++#endif
+ static void display_properties_dialog (BonoboUIComponent *uic,
+ PagerData *pager,
+ const gchar *verbname);
+@@ -277,6 +295,9 @@
+ }
+
+ static const BonoboUIVerb pager_menu_verbs [] = {
++#ifdef HAVE_LIBGNOMETSOL
++ BONOBO_UI_UNSAFE_VERB ("ChangeWorkspaceLabel", workspace_label_dialog),
++#endif
+ BONOBO_UI_UNSAFE_VERB ("PagerPreferences", display_properties_dialog),
+ BONOBO_UI_UNSAFE_VERB ("PagerHelp", display_help_dialog),
+ BONOBO_UI_UNSAFE_VERB ("PagerAbout", display_about_dialog),
+@@ -472,6 +493,31 @@
+ /* because the pager doesn't respond to signals at the moment */
+ wnck_screen_force_update (pager->screen);
+
++#ifdef HAVE_LIBGNOMETSOL
++ if (_wnck_use_trusted_extensions ()) {
++ /*
++ * Monitor all events that might require the workspace label menu
++ * to be hidden/unhidden.
++ */
++ int i, wscount;
++ WnckWorkspace *space;
++ wscount = wnck_screen_get_workspace_count (pager->screen);
++ for (i = 0; i < wscount; i++) {
++ space = wnck_screen_get_workspace (pager->screen, i);
++ g_signal_connect (G_OBJECT (space), "role_changed",
++ G_CALLBACK (role_changed),
++ (gpointer) pager);
++ }
++
++ g_signal_connect (G_OBJECT (pager->screen), "workspace_created",
++ G_CALLBACK (tsol_workspace_created),
++ (gpointer) pager);
++ g_signal_connect (G_OBJECT (pager->screen), "active_workspace_changed",
++ G_CALLBACK (changed_workspace),
++ (gpointer) pager);
++ }
++#endif
++
+ pager->pager = wnck_pager_new (pager->screen);
+ wnck_pager_set_shadow_type (WNCK_PAGER (pager->pager), GTK_SHADOW_IN);
+
+@@ -524,6 +570,25 @@
+ NULL);
+ }
+
++#ifdef HAVE_LIBGNOMETSOL
++ if (!_wnck_use_trusted_extensions ()) {
++
++ BonoboUIComponent *popup_component;
++ popup_component = panel_applet_get_popup_component (PANEL_APPLET (pager->applet));
++ bonobo_ui_component_set_prop (popup_component,
++ "/commands/ChangeWorkspaceLabel",
++ "hidden", "1",
++ NULL);
++ } else {
++ /*
++ * Trigger the active_workspace_changed callback function manually
++ * to set up the initial hidden/unhidden state of the ChangeWorkspaceLabel
++ * menu item.
++ */
++ changed_workspace (pager->screen, (gpointer) pager);
++ }
++#endif /* HAVE_LIBGNOMETSOL */
++
+ return TRUE;
+ }
+
+@@ -912,6 +977,235 @@
+ }
+ }
+
++#ifdef HAVE_LIBGNOMETSOL
++/* WARNING
++ * DON'T ever call this from outside any code that has first done
++ * a runtime trusted extension check!!! There is no point anyway.
++ */
++
++void
++lbuilder_response_cb (GtkDialog *dialog, gint id, gpointer data)
++{
++ int error;
++ m_label_t *sl = NULL;
++ char *label;
++ WnckWorkspace *space;
++
++ if (!_wnck_use_trusted_extensions ())
++ return;
++/*
++ * Stops the GNOME_LABEL_BUILDER cast calling
++ * gnome_label_builder_get_type() directly
++ */
++#define GNOME_TYPE_LABEL_BUILDER (libgnometsol_gnome_label_builder_get_type ())
++
++ GnomeLabelBuilder *lbuilder = GNOME_LABEL_BUILDER (dialog);
++ space = WNCK_WORKSPACE (data);
++
++ switch (id) {
++ case GTK_RESPONSE_OK:
++ g_object_get (G_OBJECT (lbuilder), "sl", &sl, NULL);
++
++ /* I should probably check the return code here but the label is
++ * coming from an internal function */
++ error = libtsol_label_to_str (sl, &label, M_INTERNAL, LONG_NAMES);
++ if (label != NULL) {
++ wnck_workspace_change_label (space, label);
++ }
++ g_free (label);
++ libtsol_m_label_free (sl);
++ gtk_widget_destroy (GTK_WIDGET (lbuilder));
++ ugly_showing_lbuilder_global_which_sucks_fix_me = FALSE;
++ break;
++ case GTK_RESPONSE_HELP:
++ /* show help and return control */
++ break;
++ case GTK_RESPONSE_CANCEL:
++ /* We dont want to change the workspace label so bye-bye */
++ gtk_widget_destroy (GTK_WIDGET (lbuilder));
++ ugly_showing_lbuilder_global_which_sucks_fix_me = FALSE;
++ break;
++ default:
++ /* We shouldn't really have got here */
++ break;
++ }
++
++ return;
++}
++
++static void
++tsol_workspace_created (WnckScreen *screen,
++ WnckWorkspace *space,
++ gpointer data)
++{
++ if (!_wnck_use_trusted_extensions ())
++ return;
++ g_signal_connect (G_OBJECT (space), "role_changed",
++ G_CALLBACK (role_changed),
++ data);
++}
++
++static void
++role_changed (WnckWorkspace *workspace,
++ gpointer data)
++{
++ PagerData *pager;
++ int rolewsindex;
++ int activewsindex;
++
++ if (!_wnck_use_trusted_extensions ())
++ return;
++
++ pager = (PagerData *) data;
++ rolewsindex = wnck_workspace_get_number (workspace);
++ activewsindex = wnck_workspace_get_number (wnck_screen_get_active_workspace (pager->screen));
++ /*
++ * Ignore role changes that occured outside the active workspace.
++ * The menu item is always relative to the active workspace
++ */
++ if (rolewsindex == activewsindex)
++ changed_workspace (pager->screen, pager);
++}
++
++static void
++changed_workspace (WnckScreen *screen,
++ gpointer data)
++{
++ BonoboUIComponent *popup_component;
++ PagerData *pager;
++ WnckWorkspace *workspace;
++ m_label_t *lower_sl = NULL;
++ m_label_t *upper_clear = NULL;
++ char *lower_bound = NULL;
++ char *upper_bound = NULL;
++ int error;
++ int menusensitivity = 1;
++
++ if (!_wnck_use_trusted_extensions ())
++ return;
++
++ pager = (PagerData *) data;
++
++ workspace = wnck_screen_get_active_workspace (screen);
++ error = wnck_workspace_get_label_range (workspace, &lower_bound,
++ &upper_bound);
++ if (error != 0)
++ return;
++
++ /* Convert the lower and upper bounds to internal binary labels */
++ if (libtsol_str_to_label (lower_bound, &lower_sl, MAC_LABEL, L_DEFAULT,
++ &error) < 0) {
++ g_warning ("Workspace has invalid label range min value");
++ g_free (lower_bound);
++ g_free (upper_bound);
++ return;
++ }
++ g_free (lower_bound);
++
++ if (libtsol_str_to_label (upper_bound, &upper_clear, USER_CLEAR, L_DEFAULT,
++ &error) < 0) {
++ g_warning ("Workspace has invalid label range clearance value");
++ g_free (upper_bound);
++ libtsol_m_label_free (lower_sl);
++ return;
++ }
++ g_free (upper_bound);
++
++ /* Hide/Unhide the "Change Workspace Label" menu */
++ popup_component = panel_applet_get_popup_component (PANEL_APPLET (pager->applet));
++ if (libtsol_blequal (lower_sl, upper_clear))
++ menusensitivity = 0;
++
++ libtsol_m_label_free (lower_sl);
++ libtsol_m_label_free (upper_clear);
++ bonobo_ui_component_set_prop (popup_component,
++ "/commands/ChangeWorkspaceLabel",
++ "sensitive", menusensitivity ? "1" : "0",
++ NULL);
++}
++static void
++workspace_label_dialog (BonoboUIComponent *uic,
++ PagerData *pager,
++ const gchar *verbname)
++{
++ int error = 0;
++ const char *cur_ws_label;
++ char *lower_bound = NULL;
++ char *upper_bound = NULL;
++
++ m_label_t *ws_sl = NULL;
++ m_label_t *lower_sl = NULL;
++ m_label_t *upper_clear = NULL;
++ GtkWidget *lbuilder = NULL;
++ WnckWorkspace *wspace = NULL;
++ WnckScreen *screen = pager->screen;
++
++ if (ugly_showing_lbuilder_global_which_sucks_fix_me) return;
++
++ if (!_wnck_use_trusted_extensions ())
++ return;
++
++ wspace = wnck_screen_get_active_workspace (screen);
++ error = wnck_workspace_get_label_range (wspace, &lower_bound,
++ &upper_bound);
++ if (error != 0)
++ return;
++
++ /* Convert the lower and upper bounds to internal binary labels */
++ if (libtsol_str_to_label (lower_bound, &lower_sl, MAC_LABEL, L_DEFAULT,
++ &error) < 0) {
++ g_warning ("Workspace has invalid label range minimum label");
++ g_free (lower_bound);
++ g_free (upper_bound);
++ return;
++ }
++ g_free (lower_bound);
++
++ if (libtsol_str_to_label (upper_bound, &upper_clear, USER_CLEAR, L_DEFAULT,
++ &error) < 0) {
++ g_warning ("Workspace has invalid label range");
++ g_free (upper_bound);
++ libtsol_m_label_free (lower_sl);
++ return;
++ }
++ g_free (upper_bound);
++
++ /* Get the current workspace label. */
++ cur_ws_label = wnck_workspace_get_label (wspace);
++ if (cur_ws_label != NULL) {
++ /* Convert the workspace's current label to binary type */
++ if (libtsol_str_to_label (cur_ws_label, &ws_sl, MAC_LABEL, L_DEFAULT,
++ &error) < 0) {
++ g_warning ("Workspace has an invalid label");
++ return;
++ }
++ } else {
++ g_warning ("No workspace label - defaulting to lowest in range");
++ libtsol_m_label_dup (&ws_sl, lower_sl);
++ }
++
++ lbuilder = libgnometsol_gnome_label_builder_new(_("Changing Workspace Label"),
++ upper_clear, lower_sl,
++ LBUILD_MODE_SL);
++ if (gtk_widget_has_screen (pager->applet)) {
++ gtk_window_set_screen (GTK_WINDOW (lbuilder),
++ gtk_widget_get_screen (pager->applet));
++ }
++
++ g_signal_connect (G_OBJECT (lbuilder), "response",
++ G_CALLBACK (lbuilder_response_cb), (gpointer) wspace);
++
++ gtk_widget_show_all (lbuilder);
++ ugly_showing_lbuilder_global_which_sucks_fix_me = TRUE;
++
++ /* GAH, why do I have to do this after the show? */
++ g_object_set (G_OBJECT (lbuilder), "sl", ws_sl, NULL);
++ libtsol_m_label_free (ws_sl);
++ libtsol_m_label_free (lower_sl);
++ libtsol_m_label_free (upper_clear);
++}
++#endif
++
+ static void
+ display_properties_dialog (BonoboUIComponent *uic,
+ PagerData *pager,
+diff -urN gnome-panel-2.14.1/configure.in ../SUNWgnome-panel-2.14.1.hacked/gnome-panel-2.14.1/configure.in
+--- gnome-panel-2.14.1/configure.in 2006-06-09 11:44:37.213632000 +0100
++++ ../SUNWgnome-panel-2.14.1.hacked/gnome-panel-2.14.1/configure.in 2006-06-09 13:10:34.313733000 +0100
+@@ -70,6 +70,21 @@
+ AC_SUBST(LIBPANEL_APPLET_CFLAGS)
+ AC_SUBST(LIBPANEL_APPLET_LIBS)
+
++### tsol and Xtsol lingnometsol headers
++
++found_headers=no
++case "$host" in
++ *-*-solaris*)
++ dnl Only define HAVE_LIBGNOMETSOL when all header files are found.
++ AC_CHECK_HEADERS(X11/extensions/Xtsol.h, AC_CHECK_HEADERS( sys/tsol/label_macro.h, AC_CHECK_HEADERS( libgnometsol/userattr.h, AC_CHECK_HEADERS( libgnometsol/label_builder.h, AC_DEFINE(HAVE_LIBGNOMETSOL, ,[Building with XTSOL support]) , [], [] ), [], [] ), [], [] ), [], [] )
++ ;;
++ *)
++ ;;
++esac
++
++AM_CONDITIONAL(HAVE_LIBGNOMETSOL, test x$found_headers = xyes)
++
++
+ PKG_CHECK_MODULES(WNCKLET, gdk-pixbuf-2.0 >= $GDK_PIXBUF_REQUIRED gtk+-2.0 >= $GTK_REQUIRED libgnomeui-2.0 >= $LIBGNOMEUI_REQUIRED libwnck-1.0 >= $LIBWNCK_REQUIRED libglade-2.0 >= $LIBGLADE_REQUIRED)
+ AC_SUBST(WNCKLET_CFLAGS)
+ AC_SUBST(WNCKLET_LIBS)
+diff -urN gnome-panel-2.14.1/gnome-panel/panel-run-dialog.c ../SUNWgnome-panel-2.14.1.hacked/gnome-panel-2.14.1/gnome-panel/panel-run-dialog.c
+--- gnome-panel-2.14.1/gnome-panel/panel-run-dialog.c 2006-06-09 11:44:37.230867000 +0100
++++ ../SUNWgnome-panel-2.14.1.hacked/gnome-panel-2.14.1/gnome-panel/panel-run-dialog.c 2006-06-09 15:09:04.202157000 +0100
+@@ -40,6 +40,7 @@
+ #include <glib/gi18n.h>
+ #include <gdk/gdkkeysyms.h>
+ #include <glade/glade-xml.h>
++#include <libgnome/gnome-desktop-tsol-extensions.h>
+ #include <libgnome/gnome-exec.h>
+ #include <libgnome/gnome-util.h>
+ #include <libgnomeui/gnome-entry.h>
+@@ -269,7 +270,17 @@
+ GError *error = NULL;
+ char **argv;
+ int argc;
+-
++ char *tsolcmd;
++
++ screen = gtk_window_get_screen (GTK_WINDOW (dialog->run_dialog));
++
++ if (gnome_desktop_tsol_is_multi_label_session ()) {
++ tsolcmd = g_strdup_printf ("%d:%s", gdk_screen_get_number (screen), command);
++ gnome_desktop_tsol_proxy_app_launch (tsolcmd);
++ g_free (tsolcmd);
++ return TRUE;
++ }
++
+ if (!command_is_executable (command))
+ return FALSE;
+
+--- gnome-panel-2.16.1.old/applets/wncklet/Makefile.am 2006-10-20 11:33:06.418601000 +0100
++++ gnome-panel-2.16.1/applets/wncklet/Makefile.am 2006-10-20 11:35:13.392075000 +0100
+@@ -4,6 +4,7 @@
+ -I$(top_srcdir)/libpanel-applet \
+ -I$(top_builddir)/libpanel-applet \
+ $(WNCKLET_CFLAGS) \
++ $(LIBGNOMETSOL_CFLAGS) \
+ $(DISABLE_DEPRECATED_CFLAGS) \
+ $(WARN_CFLAGS) \
+ -DGNOMELOCALEDIR=\""$(prefix)/$(DATADIRNAME)/locale"\" \
+@@ -17,6 +18,8 @@
+ WNCKLET_SOURCES = \
+ wncklet.c \
+ wncklet.h \
++ wnck-tsol.c \
++ wnck-tsol.h \
+ window-menu.c \
+ window-menu.h \
+ window-list.c \
+--- gnome-panel-2.16.1.old/config.h.in 2006-10-20 11:33:04.041224000 +0100
++++ gnome-panel-2.16.1/config.h.in 2006-10-20 11:38:29.959389000 +0100
+@@ -37,6 +37,7 @@
+ /* Defined when evolution-data-server libecal-1.2 and libedataserverui-1.2 are
+ detected */
+ #undef HAVE_LIBECAL
++#undef HAVE_LIBGNOMETSOL
+
+ /* Define to 1 if you have the <locale.h> header file. */
+ #undef HAVE_LOCALE_H
+@@ -83,6 +84,9 @@
+ /* Define to 1 if you have the <unistd.h> header file. */
+ #undef HAVE_UNISTD_H
+
++/* Defined when gnome trusted solaris extensions library libgnometsol is detected */
++#undef HAVE_LIBGNOMETSOL
++
+ /* Defined when compiling the notification-area applet in-process */
+ #undef NOTIFICATION_AREA_INPROCESS
+
+--- gnome-panel-2.16.1.old/gnome-panel/panel-action-button.c 2006-10-20 11:33:05.346353000 +0100
++++ gnome-panel-2.16.1/gnome-panel/panel-action-button.c 2006-10-20 11:46:50.497955000 +0100
+@@ -31,6 +31,7 @@
+ #include "panel-action-button.h"
+
+ #include <glib/gi18n.h>
++#include <libgnome/gnome-desktop-tsol-extensions.h>
+
+ #include "applet.h"
+ #include "menu.h"
+@@ -199,6 +200,14 @@
+ }
+
+ screen = gtk_widget_get_screen (widget);
++
++ if (gnome_desktop_tsol_is_multi_label_session()) {
++ char *cmd = g_strdup_printf ("%d:gnome-search-tool", gdk_screen_get_number (screen));
++ gnome_desktop_tsol_proxy_app_launch (cmd);
++ g_free (cmd);
++ return;
++ }
++
+ panel_launch_desktop_file ("gnome-search-tool.desktop",
+ "gnome-search-tool",
+ screen,
+@@ -234,6 +243,13 @@
+ screen = gtk_widget_get_screen (GTK_WIDGET (widget));
+ error = NULL;
+
++ if (gnome_desktop_tsol_is_multi_label_session()) {
++ char *cmd = g_strdup_printf ("%d:nautilus-connect-server", gdk_screen_get_number (screen));
++ gnome_desktop_tsol_proxy_app_launch (cmd);
++ g_free (cmd);
++ return;
++ }
++
+ gdk_spawn_command_line_on_screen (screen, "nautilus-connect-server",
+ &error);
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/gnome-panel-12-noswitchuser.diff Fri Oct 20 15:31:04 2006 +0000
@@ -0,0 +1,16 @@
+--- gnome-panel-2.14.1/gnome-panel/panel-logout.c-orig 2006-07-13 18:01:22.906575000 -0500
++++ gnome-panel-2.14.1/gnome-panel/panel-logout.c 2006-07-13 18:01:53.050421000 -0500
+@@ -304,9 +304,13 @@ panel_logout_new (PanelLogoutDialogType
+ logout_dialog->priv->default_response = PANEL_LOGOUT_DIALOG_LOGOUT;
+
+ //FIXME is gdm running?
++/*
++ * Comment "Switch User" button until VT's are supported on Solaris
++ *
+ gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
+ _("_Switch User"),
+ PANEL_LOGOUT_RESPONSE_SWITCH_USER);
++*/
+ gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_CANCEL);
--- a/patches/gnome-panel-12-trusted-extensions.diff Fri Oct 20 15:24:25 2006 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,799 +0,0 @@
-diff -urN gnome-panel-2.14.1/applets/wncklet/GNOME_WorkspaceSwitcherApplet.xml ../SUNWgnome-panel-2.14.1.hacked/gnome-panel-2.14.1/applets/wncklet/GNOME_WorkspaceSwitcherApplet.xml
---- gnome-panel-2.14.1/applets/wncklet/GNOME_WorkspaceSwitcherApplet.xml 2004-06-11 11:53:17.000000000 +0100
-+++ ../SUNWgnome-panel-2.14.1.hacked/gnome-panel-2.14.1/applets/wncklet/GNOME_WorkspaceSwitcherApplet.xml 2006-06-09 12:48:59.580890000 +0100
-@@ -1,6 +1,8 @@
- <Root>
- <popups>
- <popup name="button3">
-+ <menuitem name="Workspace Label Item" verb="ChangeWorkspaceLabel" _label="_Change Workspace Label..."/>
-+ <separator/>
- <menuitem name="Pager Preferences Item" verb="PagerPreferences" _label="_Preferences"
- pixtype="stock" pixname="gtk-properties"/>
- <menuitem name="Pager Help Item" verb="PagerHelp" _label="_Help"
-diff -urN gnome-panel-2.14.1/applets/wncklet/wnck-tsol.c ../SUNWgnome-panel-2.14.1.hacked/gnome-panel-2.14.1/applets/wncklet/wnck-tsol.c
---- gnome-panel-2.14.1/applets/wncklet/wnck-tsol.c 1970-01-01 01:00:00.000000000 +0100
-+++ ../SUNWgnome-panel-2.14.1.hacked/gnome-panel-2.14.1/applets/wncklet/wnck-tsol.c 2006-06-09 16:31:40.489536000 +0100
-@@ -0,0 +1,217 @@
-+#include <config.h>
-+#ifdef HAVE_LIBGNOMETSOL
-+
-+#include <stdlib.h>
-+#include <string.h>
-+#include <dlfcn.h>
-+#include <link.h>
-+#include <glib.h>
-+#include <panel-applet.h>
-+#include "wnck-tsol.h"
-+#define WNCK_I_KNOW_THIS_IS_UNSTABLE
-+#include <libwnck/libwnck.h>
-+
-+static
-+void * dlopen_tsol (void)
-+{
-+ void *handle = NULL;
-+
-+ /*
-+ * No 64-bit version of libwnck so we can get away with hardcoding
-+ * to a single path on this occasion
-+ */
-+ if ((handle = dlopen ("/usr/lib/libtsol.so.2", RTLD_LAZY)) != NULL)
-+ return handle;
-+
-+ return handle;
-+}
-+
-+static
-+void * dlopen_xtsol (void)
-+{
-+ void *handle = NULL;
-+
-+ if ((handle = dlopen ("/usr/lib/libXtsol.so.1", RTLD_LAZY)) != NULL)
-+ return handle;
-+ if ((handle = dlopen ("/usr/openwin/lib/libXtsol.so.1", RTLD_LAZY)) != NULL)
-+ return handle;
-+
-+ return handle;
-+}
-+
-+static
-+void * dlopen_gnometsol (void)
-+{
-+ void *handle = NULL;
-+
-+ if ((handle = dlopen ("/usr/lib/libgnometsol.so", RTLD_LAZY)) != NULL)
-+ return handle;
-+
-+ return handle;
-+}
-+
-+
-+gboolean
-+_wnck_use_trusted_extensions (void)
-+{
-+ static int trusted = -1;
-+
-+ /*
-+ * Sun Trusted Extensions (tm) for Solaris (tm) support. (Damn I should be a lawyer).
-+ *
-+ * It is necessary to use dlopen because the label aware extensions to libwnck work
-+ * only on systems with the trusted extensions installed and with the SUN_TSOL
-+ * xserver extension present
-+ */
-+
-+ if (trusted < 0) {
-+ static gpointer tsol_handle = NULL;
-+ static gpointer xtsol_handle = NULL;
-+ static gpointer gnometsol_handle = NULL;
-+
-+ if (getenv ("TRUSTED_SESSION") == NULL) {
-+ trusted = 0;
-+ return 0;
-+ }
-+
-+ tsol_handle = dlopen_tsol ();
-+ if (tsol_handle != NULL)
-+ xtsol_handle = dlopen_xtsol ();
-+ if (tsol_handle && xtsol_handle) {
-+
-+ /* libtsol functions */
-+ libtsol_blequal = (tsol_blequal) dlsym (tsol_handle, "blequal");
-+ libtsol_label_to_str = (tsol_label_to_str) dlsym (tsol_handle, "label_to_str");
-+ libtsol_str_to_label = (tsol_str_to_label) dlsym (tsol_handle, "str_to_label");
-+ libtsol_m_label_dup = (tsol_m_label_dup) dlsym (tsol_handle, "m_label_dup");
-+ libtsol_m_label_free = (tsol_m_label_free) dlsym (tsol_handle, "m_label_free");
-+
-+ /* Other misc. libtsol functions */
-+ libtsol_blminimum = (tsol_blminimum) dlsym (tsol_handle, "blminimum");
-+ libtsol_blmaximum = (tsol_blmaximum) dlsym (tsol_handle, "blmaximum");
-+ libtsol_blinrange = (tsol_blinrange) dlsym (tsol_handle, "blinrange");
-+ libtsol_getuserrange = (tsol_getuserrange) dlsym (tsol_handle, "getuserrange");
-+ libtsol_blabel_alloc = (tsol_blabel_alloc) dlsym (tsol_handle, "blabel_alloc");
-+ libtsol_blabel_free = (tsol_blabel_free) dlsym (tsol_handle, "blabel_free");
-+ libtsol_bsllow = (tsol_bsllow) dlsym (tsol_handle, "bsllow");
-+ libtsol_bslhigh = (tsol_bslhigh) dlsym (tsol_handle, "bslhigh");
-+
-+ /* libXtsol functions */
-+ libxtsol_XTSOLgetClientLabel = (xtsol_XTSOLgetClientLabel) dlsym (xtsol_handle,
-+ "XTSOLgetClientLabel");
-+ libxtsol_XTSOLIsWindowTrusted = (xtsol_XTSOLIsWindowTrusted) dlsym (xtsol_handle,
-+ "XTSOLIsWindowTrusted");
-+
-+ if (libtsol_label_to_str == NULL ||
-+ libtsol_str_to_label == NULL ||
-+ libtsol_m_label_dup == NULL ||
-+ libtsol_m_label_free == NULL ||
-+ libtsol_blminimum == NULL ||
-+ libtsol_blmaximum == NULL ||
-+ libtsol_blinrange == NULL ||
-+ libtsol_getuserrange == NULL ||
-+ libtsol_blabel_alloc == NULL ||
-+ libtsol_blabel_free == NULL ||
-+ libtsol_bsllow == NULL ||
-+ libtsol_bslhigh == NULL ||
-+ libxtsol_XTSOLgetClientLabel == NULL ||
-+ libxtsol_XTSOLIsWindowTrusted == NULL) {
-+ dlclose (tsol_handle);
-+ dlclose (xtsol_handle);
-+ tsol_handle = NULL;
-+ xtsol_handle = NULL;
-+ }
-+ }
-+ gnometsol_handle = dlopen_gnometsol ();
-+ if (gnometsol_handle != NULL) {
-+ libgnometsol_gnome_label_builder_new =
-+ (gnometsol_gnome_label_builder_new) dlsym (gnometsol_handle,
-+ "gnome_label_builder_new");
-+ libgnometsol_gnome_label_builder_get_type =
-+ (gnometsol_gnome_label_builder_get_type) dlsym (gnometsol_handle,
-+ "gnome_label_builder_get_type");
-+ if (libgnometsol_gnome_label_builder_new == NULL ||
-+ libgnometsol_gnome_label_builder_get_type == NULL)
-+ gnometsol_handle = NULL;
-+ }
-+ trusted = ((tsol_handle != NULL) && (xtsol_handle != NULL) && (gnometsol_handle != NULL)) ? 1 : 0;
-+ }
-+ return trusted ? TRUE : FALSE;
-+}
-+
-+const char *
-+_wnck_get_min_label ()
-+{
-+ static char *min_label = NULL;
-+
-+ if (!min_label) {
-+ min_label = (char *) getenv ("USER_MIN_SL");
-+ }
-+ return min_label;
-+}
-+
-+const char*
-+_wnck_get_max_label()
-+{
-+ static char *max_label = NULL;
-+
-+ if (!max_label) {
-+ max_label = (char *) getenv ("USER_MAX_SL");
-+ }
-+ return max_label;
-+}
-+
-+
-+/* window selector part */
-+
-+static gboolean tsol_win_selector_label_expose_event (GtkWidget *widget,
-+ GdkEventExpose *event,
-+ gpointer data)
-+{
-+ WnckWindow *window = (WnckWindow *) data;
-+
-+ GdkGC *tmp_gc = gdk_gc_new (widget->window);
-+ gdk_gc_set_rgb_fg_color (tmp_gc, wnck_window_get_label_color (window));
-+
-+ gdk_draw_rectangle (widget->window,
-+ widget->style->black_gc,
-+ FALSE,
-+ event->area.x, event->area.y,
-+ event->area.width - 1, event->area.height - 1);
-+
-+ gdk_draw_rectangle (widget->window,
-+ tmp_gc,
-+ TRUE,
-+ event->area.x + 1, event->area.y + 1,
-+ event->area.width - 2, event->area.height - 2);
-+
-+ g_object_unref (tmp_gc);
-+
-+ return FALSE;
-+}
-+
-+GtkWidget *
-+window_menu_create_label_indicator (WnckWindow *window,
-+ GtkWidget *image)
-+{
-+ GtkWidget *da, *hbox;
-+ da = gtk_drawing_area_new ();
-+
-+ g_signal_connect (G_OBJECT (da), "expose_event",
-+ G_CALLBACK (tsol_win_selector_label_expose_event),
-+ window);
-+
-+ gtk_widget_set_size_request (da, 5, -1);
-+
-+ hbox = gtk_hbox_new (FALSE, 4);
-+
-+ gtk_container_add (GTK_CONTAINER (hbox), da);
-+ gtk_container_add (GTK_CONTAINER (hbox), image);
-+
-+ gtk_widget_show (da);
-+ gtk_widget_show (hbox);
-+ gtk_widget_show (image);
-+
-+ return hbox;
-+}
-+#endif /* HAVE_LIBGNOMETSOL */
-diff -urN gnome-panel-2.14.1/applets/wncklet/wnck-tsol.h ../SUNWgnome-panel-2.14.1.hacked/gnome-panel-2.14.1/applets/wncklet/wnck-tsol.h
---- gnome-panel-2.14.1/applets/wncklet/wnck-tsol.h 1970-01-01 01:00:00.000000000 +0100
-+++ ../SUNWgnome-panel-2.14.1.hacked/gnome-panel-2.14.1/applets/wncklet/wnck-tsol.h 2006-06-09 16:31:40.489611000 +0100
-@@ -0,0 +1,83 @@
-+#ifndef __WNCK_TSOL_H__
-+#define __WNCK_TSOL_H__
-+
-+#include <config.h>
-+
-+#ifdef HAVE_LIBGNOMETSOL
-+#include <glib-2.0/glib.h>
-+#include <panel-applet.h>
-+#include <tsol/label.h>
-+#include <sys/tsol/label_macro.h>
-+#include <X11/Xlib.h>
-+#include <X11/extensions/Xtsol.h>
-+#include <libgnometsol/label_builder.h>
-+#define WNCK_I_KNOW_THIS_IS_UNSTABLE
-+#include <libwnck/libwnck.h>
-+
-+/* Libtsol functions */
-+
-+typedef int (*tsol_blequal) (const m_label_t *label1, const m_label_t *label2);
-+typedef int (*tsol_label_to_str) (const m_label_t *label, char **string,
-+ const m_label_str_t conversion_type,
-+ uint_t flags);
-+typedef int (*tsol_str_to_label) (const char *string, m_label_t **label,
-+ const m_label_type_t label_type, uint_t flags,
-+ int *error);
-+typedef void (*tsol_m_label_dup) (m_label_t **dst, const m_label_t *src);
-+typedef void (*tsol_m_label_free) (m_label_t *label);
-+
-+/* Other misc. libtsol functions that seem to be stable */
-+typedef blrange_t* (*tsol_getuserrange) (const char *username);
-+typedef int (*tsol_blinrange) (const m_label_t *label,
-+ const blrange_t *range);
-+typedef void (*tsol_blminimum) (m_label_t *minimum_label,
-+ const m_label_t *bounding_label);
-+typedef void (*tsol_blmaximum) (m_label_t *maximum_label,
-+ const m_label_t *bounding_label);
-+typedef m_label_t* (*tsol_blabel_alloc) (void);
-+typedef void (*tsol_blabel_free) (m_label_t *label_p);
-+typedef void (*tsol_bsllow) (m_label_t *label);
-+typedef void (*tsol_bslhigh) (m_label_t *label);
-+
-+/* libXtsol functions */
-+typedef Status (*xtsol_XTSOLgetClientLabel) (Display *dpy, XID xid,
-+ bslabel_t *sl);
-+typedef Bool (*xtsol_XTSOLIsWindowTrusted) (Display *dpy, Window win);
-+
-+extern gboolean _trusted_extensions_initialised;
-+
-+/* libgnometsol functions */
-+typedef GtkWidget* (*gnometsol_gnome_label_builder_new) (char *msg,
-+ blevel_t *upper, blevel_t *lower, int mode);
-+typedef GType (*gnometsol_gnome_label_builder_get_type) (void);
-+
-+/* libtsol functions */
-+tsol_blequal libtsol_blequal;
-+tsol_label_to_str libtsol_label_to_str;
-+tsol_str_to_label libtsol_str_to_label;
-+tsol_m_label_dup libtsol_m_label_dup;
-+tsol_m_label_free libtsol_m_label_free;
-+/* Other misc. libtsol functions */
-+tsol_blminimum libtsol_blminimum;
-+tsol_blmaximum libtsol_blmaximum;
-+tsol_blinrange libtsol_blinrange;
-+tsol_getuserrange libtsol_getuserrange;
-+tsol_blabel_alloc libtsol_blabel_alloc;
-+tsol_blabel_free libtsol_blabel_free;
-+tsol_bsllow libtsol_bsllow;
-+tsol_bslhigh libtsol_bslhigh;
-+
-+xtsol_XTSOLgetClientLabel libxtsol_XTSOLgetClientLabel;
-+xtsol_XTSOLIsWindowTrusted libxtsol_XTSOLIsWindowTrusted;
-+
-+gnometsol_gnome_label_builder_new libgnometsol_gnome_label_builder_new;
-+gnometsol_gnome_label_builder_get_type libgnometsol_gnome_label_builder_get_type;
-+
-+gboolean _wnck_use_trusted_extensions ();
-+const char* _wnck_get_min_label ();
-+const char* _wnck_get_max_label ();
-+
-+GtkWidget* window_menu_create_label_indicator (WnckWindow *window,
-+ GtkWidget *image);
-+#endif /* HAVE_LIBGNOMETSOL */
-+#endif
-diff -urN gnome-panel-2.14.1/applets/wncklet/workspace-switcher.c ../SUNWgnome-panel-2.14.1.hacked/gnome-panel-2.14.1/applets/wncklet/workspace-switcher.c
---- gnome-panel-2.14.1/applets/wncklet/workspace-switcher.c 2006-03-06 21:41:15.000000000 +0000
-+++ ../SUNWgnome-panel-2.14.1.hacked/gnome-panel-2.14.1/applets/wncklet/workspace-switcher.c 2006-06-09 16:40:30.737645000 +0100
-@@ -27,6 +27,10 @@
- #include <gconf/gconf-client.h>
- #include <libgnomeui/gnome-help.h>
-
-+#ifdef HAVE_LIBGNOMETSOL
-+#include "wnck-tsol.h"
-+#endif
-+
- #include "workspace-switcher.h"
-
- #include "wncklet.h"
-@@ -39,6 +43,8 @@
- #define NUM_WORKSPACES "/apps/metacity/general/num_workspaces"
- #define WORKSPACE_NAME "/apps/metacity/workspace_names/name_1"
-
-+gboolean ugly_showing_lbuilder_global_which_sucks_fix_me = FALSE;
-+
- typedef struct {
- GtkWidget *applet;
-
-@@ -68,6 +74,18 @@
- guint listeners [3];
- } PagerData;
-
-+#ifdef HAVE_LIBGNOMETSOL
-+static void tsol_workspace_created (WnckScreen *screen,
-+ WnckWorkspace *workspace,
-+ gpointer data);
-+static void role_changed (WnckWorkspace *workspace,
-+ gpointer data);
-+static void changed_workspace (WnckScreen *screen,
-+ gpointer data);
-+static void workspace_label_dialog (BonoboUIComponent *uic,
-+ PagerData *pager,
-+ const gchar *verbname);
-+#endif
- static void display_properties_dialog (BonoboUIComponent *uic,
- PagerData *pager,
- const gchar *verbname);
-@@ -277,6 +295,9 @@
- }
-
- static const BonoboUIVerb pager_menu_verbs [] = {
-+#ifdef HAVE_LIBGNOMETSOL
-+ BONOBO_UI_UNSAFE_VERB ("ChangeWorkspaceLabel", workspace_label_dialog),
-+#endif
- BONOBO_UI_UNSAFE_VERB ("PagerPreferences", display_properties_dialog),
- BONOBO_UI_UNSAFE_VERB ("PagerHelp", display_help_dialog),
- BONOBO_UI_UNSAFE_VERB ("PagerAbout", display_about_dialog),
-@@ -472,6 +493,31 @@
- /* because the pager doesn't respond to signals at the moment */
- wnck_screen_force_update (pager->screen);
-
-+#ifdef HAVE_LIBGNOMETSOL
-+ if (_wnck_use_trusted_extensions ()) {
-+ /*
-+ * Monitor all events that might require the workspace label menu
-+ * to be hidden/unhidden.
-+ */
-+ int i, wscount;
-+ WnckWorkspace *space;
-+ wscount = wnck_screen_get_workspace_count (pager->screen);
-+ for (i = 0; i < wscount; i++) {
-+ space = wnck_screen_get_workspace (pager->screen, i);
-+ g_signal_connect (G_OBJECT (space), "role_changed",
-+ G_CALLBACK (role_changed),
-+ (gpointer) pager);
-+ }
-+
-+ g_signal_connect (G_OBJECT (pager->screen), "workspace_created",
-+ G_CALLBACK (tsol_workspace_created),
-+ (gpointer) pager);
-+ g_signal_connect (G_OBJECT (pager->screen), "active_workspace_changed",
-+ G_CALLBACK (changed_workspace),
-+ (gpointer) pager);
-+ }
-+#endif
-+
- pager->pager = wnck_pager_new (pager->screen);
- wnck_pager_set_shadow_type (WNCK_PAGER (pager->pager), GTK_SHADOW_IN);
-
-@@ -524,6 +570,25 @@
- NULL);
- }
-
-+#ifdef HAVE_LIBGNOMETSOL
-+ if (!_wnck_use_trusted_extensions ()) {
-+
-+ BonoboUIComponent *popup_component;
-+ popup_component = panel_applet_get_popup_component (PANEL_APPLET (pager->applet));
-+ bonobo_ui_component_set_prop (popup_component,
-+ "/commands/ChangeWorkspaceLabel",
-+ "hidden", "1",
-+ NULL);
-+ } else {
-+ /*
-+ * Trigger the active_workspace_changed callback function manually
-+ * to set up the initial hidden/unhidden state of the ChangeWorkspaceLabel
-+ * menu item.
-+ */
-+ changed_workspace (pager->screen, (gpointer) pager);
-+ }
-+#endif /* HAVE_LIBGNOMETSOL */
-+
- return TRUE;
- }
-
-@@ -912,6 +977,235 @@
- }
- }
-
-+#ifdef HAVE_LIBGNOMETSOL
-+/* WARNING
-+ * DON'T ever call this from outside any code that has first done
-+ * a runtime trusted extension check!!! There is no point anyway.
-+ */
-+
-+void
-+lbuilder_response_cb (GtkDialog *dialog, gint id, gpointer data)
-+{
-+ int error;
-+ m_label_t *sl = NULL;
-+ char *label;
-+ WnckWorkspace *space;
-+
-+ if (!_wnck_use_trusted_extensions ())
-+ return;
-+/*
-+ * Stops the GNOME_LABEL_BUILDER cast calling
-+ * gnome_label_builder_get_type() directly
-+ */
-+#define GNOME_TYPE_LABEL_BUILDER (libgnometsol_gnome_label_builder_get_type ())
-+
-+ GnomeLabelBuilder *lbuilder = GNOME_LABEL_BUILDER (dialog);
-+ space = WNCK_WORKSPACE (data);
-+
-+ switch (id) {
-+ case GTK_RESPONSE_OK:
-+ g_object_get (G_OBJECT (lbuilder), "sl", &sl, NULL);
-+
-+ /* I should probably check the return code here but the label is
-+ * coming from an internal function */
-+ error = libtsol_label_to_str (sl, &label, M_INTERNAL, LONG_NAMES);
-+ if (label != NULL) {
-+ wnck_workspace_change_label (space, label);
-+ }
-+ g_free (label);
-+ libtsol_m_label_free (sl);
-+ gtk_widget_destroy (GTK_WIDGET (lbuilder));
-+ ugly_showing_lbuilder_global_which_sucks_fix_me = FALSE;
-+ break;
-+ case GTK_RESPONSE_HELP:
-+ /* show help and return control */
-+ break;
-+ case GTK_RESPONSE_CANCEL:
-+ /* We dont want to change the workspace label so bye-bye */
-+ gtk_widget_destroy (GTK_WIDGET (lbuilder));
-+ ugly_showing_lbuilder_global_which_sucks_fix_me = FALSE;
-+ break;
-+ default:
-+ /* We shouldn't really have got here */
-+ break;
-+ }
-+
-+ return;
-+}
-+
-+static void
-+tsol_workspace_created (WnckScreen *screen,
-+ WnckWorkspace *space,
-+ gpointer data)
-+{
-+ if (!_wnck_use_trusted_extensions ())
-+ return;
-+ g_signal_connect (G_OBJECT (space), "role_changed",
-+ G_CALLBACK (role_changed),
-+ data);
-+}
-+
-+static void
-+role_changed (WnckWorkspace *workspace,
-+ gpointer data)
-+{
-+ PagerData *pager;
-+ int rolewsindex;
-+ int activewsindex;
-+
-+ if (!_wnck_use_trusted_extensions ())
-+ return;
-+
-+ pager = (PagerData *) data;
-+ rolewsindex = wnck_workspace_get_number (workspace);
-+ activewsindex = wnck_workspace_get_number (wnck_screen_get_active_workspace (pager->screen));
-+ /*
-+ * Ignore role changes that occured outside the active workspace.
-+ * The menu item is always relative to the active workspace
-+ */
-+ if (rolewsindex == activewsindex)
-+ changed_workspace (pager->screen, pager);
-+}
-+
-+static void
-+changed_workspace (WnckScreen *screen,
-+ gpointer data)
-+{
-+ BonoboUIComponent *popup_component;
-+ PagerData *pager;
-+ WnckWorkspace *workspace;
-+ m_label_t *lower_sl = NULL;
-+ m_label_t *upper_clear = NULL;
-+ char *lower_bound = NULL;
-+ char *upper_bound = NULL;
-+ int error;
-+ int menusensitivity = 1;
-+
-+ if (!_wnck_use_trusted_extensions ())
-+ return;
-+
-+ pager = (PagerData *) data;
-+
-+ workspace = wnck_screen_get_active_workspace (screen);
-+ error = wnck_workspace_get_label_range (workspace, &lower_bound,
-+ &upper_bound);
-+ if (error != 0)
-+ return;
-+
-+ /* Convert the lower and upper bounds to internal binary labels */
-+ if (libtsol_str_to_label (lower_bound, &lower_sl, MAC_LABEL, L_DEFAULT,
-+ &error) < 0) {
-+ g_warning ("Workspace has invalid label range min value");
-+ g_free (lower_bound);
-+ g_free (upper_bound);
-+ return;
-+ }
-+ g_free (lower_bound);
-+
-+ if (libtsol_str_to_label (upper_bound, &upper_clear, USER_CLEAR, L_DEFAULT,
-+ &error) < 0) {
-+ g_warning ("Workspace has invalid label range clearance value");
-+ g_free (upper_bound);
-+ libtsol_m_label_free (lower_sl);
-+ return;
-+ }
-+ g_free (upper_bound);
-+
-+ /* Hide/Unhide the "Change Workspace Label" menu */
-+ popup_component = panel_applet_get_popup_component (PANEL_APPLET (pager->applet));
-+ if (libtsol_blequal (lower_sl, upper_clear))
-+ menusensitivity = 0;
-+
-+ libtsol_m_label_free (lower_sl);
-+ libtsol_m_label_free (upper_clear);
-+ bonobo_ui_component_set_prop (popup_component,
-+ "/commands/ChangeWorkspaceLabel",
-+ "sensitive", menusensitivity ? "1" : "0",
-+ NULL);
-+}
-+static void
-+workspace_label_dialog (BonoboUIComponent *uic,
-+ PagerData *pager,
-+ const gchar *verbname)
-+{
-+ int error = 0;
-+ const char *cur_ws_label;
-+ char *lower_bound = NULL;
-+ char *upper_bound = NULL;
-+
-+ m_label_t *ws_sl = NULL;
-+ m_label_t *lower_sl = NULL;
-+ m_label_t *upper_clear = NULL;
-+ GtkWidget *lbuilder = NULL;
-+ WnckWorkspace *wspace = NULL;
-+ WnckScreen *screen = pager->screen;
-+
-+ if (ugly_showing_lbuilder_global_which_sucks_fix_me) return;
-+
-+ if (!_wnck_use_trusted_extensions ())
-+ return;
-+
-+ wspace = wnck_screen_get_active_workspace (screen);
-+ error = wnck_workspace_get_label_range (wspace, &lower_bound,
-+ &upper_bound);
-+ if (error != 0)
-+ return;
-+
-+ /* Convert the lower and upper bounds to internal binary labels */
-+ if (libtsol_str_to_label (lower_bound, &lower_sl, MAC_LABEL, L_DEFAULT,
-+ &error) < 0) {
-+ g_warning ("Workspace has invalid label range minimum label");
-+ g_free (lower_bound);
-+ g_free (upper_bound);
-+ return;
-+ }
-+ g_free (lower_bound);
-+
-+ if (libtsol_str_to_label (upper_bound, &upper_clear, USER_CLEAR, L_DEFAULT,
-+ &error) < 0) {
-+ g_warning ("Workspace has invalid label range");
-+ g_free (upper_bound);
-+ libtsol_m_label_free (lower_sl);
-+ return;
-+ }
-+ g_free (upper_bound);
-+
-+ /* Get the current workspace label. */
-+ cur_ws_label = wnck_workspace_get_label (wspace);
-+ if (cur_ws_label != NULL) {
-+ /* Convert the workspace's current label to binary type */
-+ if (libtsol_str_to_label (cur_ws_label, &ws_sl, MAC_LABEL, L_DEFAULT,
-+ &error) < 0) {
-+ g_warning ("Workspace has an invalid label");
-+ return;
-+ }
-+ } else {
-+ g_warning ("No workspace label - defaulting to lowest in range");
-+ libtsol_m_label_dup (&ws_sl, lower_sl);
-+ }
-+
-+ lbuilder = libgnometsol_gnome_label_builder_new(_("Changing Workspace Label"),
-+ upper_clear, lower_sl,
-+ LBUILD_MODE_SL);
-+ if (gtk_widget_has_screen (pager->applet)) {
-+ gtk_window_set_screen (GTK_WINDOW (lbuilder),
-+ gtk_widget_get_screen (pager->applet));
-+ }
-+
-+ g_signal_connect (G_OBJECT (lbuilder), "response",
-+ G_CALLBACK (lbuilder_response_cb), (gpointer) wspace);
-+
-+ gtk_widget_show_all (lbuilder);
-+ ugly_showing_lbuilder_global_which_sucks_fix_me = TRUE;
-+
-+ /* GAH, why do I have to do this after the show? */
-+ g_object_set (G_OBJECT (lbuilder), "sl", ws_sl, NULL);
-+ libtsol_m_label_free (ws_sl);
-+ libtsol_m_label_free (lower_sl);
-+ libtsol_m_label_free (upper_clear);
-+}
-+#endif
-+
- static void
- display_properties_dialog (BonoboUIComponent *uic,
- PagerData *pager,
-diff -urN gnome-panel-2.14.1/configure.in ../SUNWgnome-panel-2.14.1.hacked/gnome-panel-2.14.1/configure.in
---- gnome-panel-2.14.1/configure.in 2006-06-09 11:44:37.213632000 +0100
-+++ ../SUNWgnome-panel-2.14.1.hacked/gnome-panel-2.14.1/configure.in 2006-06-09 13:10:34.313733000 +0100
-@@ -70,6 +70,21 @@
- AC_SUBST(LIBPANEL_APPLET_CFLAGS)
- AC_SUBST(LIBPANEL_APPLET_LIBS)
-
-+### tsol and Xtsol lingnometsol headers
-+
-+found_headers=no
-+case "$host" in
-+ *-*-solaris*)
-+ dnl Only define HAVE_LIBGNOMETSOL when all header files are found.
-+ AC_CHECK_HEADERS(X11/extensions/Xtsol.h, AC_CHECK_HEADERS( sys/tsol/label_macro.h, AC_CHECK_HEADERS( libgnometsol/userattr.h, AC_CHECK_HEADERS( libgnometsol/label_builder.h, AC_DEFINE(HAVE_LIBGNOMETSOL, ,[Building with XTSOL support]) , [], [] ), [], [] ), [], [] ), [], [] )
-+ ;;
-+ *)
-+ ;;
-+esac
-+
-+AM_CONDITIONAL(HAVE_LIBGNOMETSOL, test x$found_headers = xyes)
-+
-+
- PKG_CHECK_MODULES(WNCKLET, gdk-pixbuf-2.0 >= $GDK_PIXBUF_REQUIRED gtk+-2.0 >= $GTK_REQUIRED libgnomeui-2.0 >= $LIBGNOMEUI_REQUIRED libwnck-1.0 >= $LIBWNCK_REQUIRED libglade-2.0 >= $LIBGLADE_REQUIRED)
- AC_SUBST(WNCKLET_CFLAGS)
- AC_SUBST(WNCKLET_LIBS)
-diff -urN gnome-panel-2.14.1/gnome-panel/panel-run-dialog.c ../SUNWgnome-panel-2.14.1.hacked/gnome-panel-2.14.1/gnome-panel/panel-run-dialog.c
---- gnome-panel-2.14.1/gnome-panel/panel-run-dialog.c 2006-06-09 11:44:37.230867000 +0100
-+++ ../SUNWgnome-panel-2.14.1.hacked/gnome-panel-2.14.1/gnome-panel/panel-run-dialog.c 2006-06-09 15:09:04.202157000 +0100
-@@ -40,6 +40,7 @@
- #include <glib/gi18n.h>
- #include <gdk/gdkkeysyms.h>
- #include <glade/glade-xml.h>
-+#include <libgnome/gnome-desktop-tsol-extensions.h>
- #include <libgnome/gnome-exec.h>
- #include <libgnome/gnome-util.h>
- #include <libgnomeui/gnome-entry.h>
-@@ -269,7 +270,17 @@
- GError *error = NULL;
- char **argv;
- int argc;
--
-+ char *tsolcmd;
-+
-+ screen = gtk_window_get_screen (GTK_WINDOW (dialog->run_dialog));
-+
-+ if (gnome_desktop_tsol_is_multi_label_session ()) {
-+ tsolcmd = g_strdup_printf ("%d:%s", gdk_screen_get_number (screen), command);
-+ gnome_desktop_tsol_proxy_app_launch (tsolcmd);
-+ g_free (tsolcmd);
-+ return TRUE;
-+ }
-+
- if (!command_is_executable (command))
- return FALSE;
-
---- gnome-panel-2.16.1.old/applets/wncklet/Makefile.am 2006-10-20 11:33:06.418601000 +0100
-+++ gnome-panel-2.16.1/applets/wncklet/Makefile.am 2006-10-20 11:35:13.392075000 +0100
-@@ -4,6 +4,7 @@
- -I$(top_srcdir)/libpanel-applet \
- -I$(top_builddir)/libpanel-applet \
- $(WNCKLET_CFLAGS) \
-+ $(LIBGNOMETSOL_CFLAGS) \
- $(DISABLE_DEPRECATED_CFLAGS) \
- $(WARN_CFLAGS) \
- -DGNOMELOCALEDIR=\""$(prefix)/$(DATADIRNAME)/locale"\" \
-@@ -17,6 +18,8 @@
- WNCKLET_SOURCES = \
- wncklet.c \
- wncklet.h \
-+ wnck-tsol.c \
-+ wnck-tsol.h \
- window-menu.c \
- window-menu.h \
- window-list.c \
---- gnome-panel-2.16.1.old/config.h.in 2006-10-20 11:33:04.041224000 +0100
-+++ gnome-panel-2.16.1/config.h.in 2006-10-20 11:38:29.959389000 +0100
-@@ -37,6 +37,7 @@
- /* Defined when evolution-data-server libecal-1.2 and libedataserverui-1.2 are
- detected */
- #undef HAVE_LIBECAL
-+#undef HAVE_LIBGNOMETSOL
-
- /* Define to 1 if you have the <locale.h> header file. */
- #undef HAVE_LOCALE_H
-@@ -83,6 +84,9 @@
- /* Define to 1 if you have the <unistd.h> header file. */
- #undef HAVE_UNISTD_H
-
-+/* Defined when gnome trusted solaris extensions library libgnometsol is detected */
-+#undef HAVE_LIBGNOMETSOL
-+
- /* Defined when compiling the notification-area applet in-process */
- #undef NOTIFICATION_AREA_INPROCESS
-
---- gnome-panel-2.16.1.old/gnome-panel/panel-action-button.c 2006-10-20 11:33:05.346353000 +0100
-+++ gnome-panel-2.16.1/gnome-panel/panel-action-button.c 2006-10-20 11:46:50.497955000 +0100
-@@ -31,6 +31,7 @@
- #include "panel-action-button.h"
-
- #include <glib/gi18n.h>
-+#include <libgnome/gnome-desktop-tsol-extensions.h>
-
- #include "applet.h"
- #include "menu.h"
-@@ -199,6 +200,14 @@
- }
-
- screen = gtk_widget_get_screen (widget);
-+
-+ if (gnome_desktop_tsol_is_multi_label_session()) {
-+ char *cmd = g_strdup_printf ("%d:gnome-search-tool", gdk_screen_get_number (screen));
-+ gnome_desktop_tsol_proxy_app_launch (cmd);
-+ g_free (cmd);
-+ return;
-+ }
-+
- panel_launch_desktop_file ("gnome-search-tool.desktop",
- "gnome-search-tool",
- screen,
-@@ -234,6 +243,13 @@
- screen = gtk_widget_get_screen (GTK_WIDGET (widget));
- error = NULL;
-
-+ if (gnome_desktop_tsol_is_multi_label_session()) {
-+ char *cmd = g_strdup_printf ("%d:nautilus-connect-server", gdk_screen_get_number (screen));
-+ gnome_desktop_tsol_proxy_app_launch (cmd);
-+ g_free (cmd);
-+ return;
-+ }
-+
- gdk_spawn_command_line_on_screen (screen, "nautilus-connect-server",
- &error);
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/gnome-panel-13-lockdown-applets.diff Fri Oct 20 15:31:04 2006 +0000
@@ -0,0 +1,469 @@
+--- gnome-panel-2.15.91.old/gnome-panel/panel-applet-frame.h 2006-08-09 15:43:31.452059000 +0100
++++ gnome-panel-2.15.91/gnome-panel/panel-applet-frame.h 2006-08-09 16:37:36.089721000 +0100
+@@ -78,6 +78,14 @@
+ void panel_applet_frame_set_panel (PanelAppletFrame *frame,
+ PanelWidget *panel);
+
++/**
++ * Checks whether the applet has been disabled or reenabled and if necessary
++ * rebuilds the applet.
++ * Returns true if the applet frame was rebuilt as a result of its restriction
++ * status changing.
++ */
++gboolean panel_applet_frame_refresh (PanelAppletFrame *frame);
++
+ G_END_DECLS
+
+ #endif /* __PANEL_APPLET_FRAME_H__ */
+--- gnome-panel-2.15.91.old/gnome-panel/panel-applet-frame.c 2006-08-09 15:43:31.125609000 +0100
++++ gnome-panel-2.15.91/gnome-panel/panel-applet-frame.c 2006-08-09 17:55:28.281987000 +0100
+@@ -116,6 +116,10 @@
+ gboolean movable;
+ gboolean removable;
+
++ /* If the applet is currently in a disabled state, no need for a menu */
++ if (frame->priv->ui_component == NULL)
++ return;
++
+ panel_widget = PANEL_WIDGET (GTK_WIDGET (frame)->parent);
+
+ lockable = panel_applet_lockable (frame->priv->applet_info);
+@@ -324,17 +328,12 @@
+ const char *id)
+ {
+ PanelAppletFrame *frame;
+- CORBA_Environment ev;
+- char *moniker;
+ PanelAppletFrameActivating *frame_act;
+
+ g_return_if_fail (iid != NULL);
+ g_return_if_fail (panel != NULL);
+ g_return_if_fail (id != NULL);
+
+- if (panel_lockdown_is_applet_disabled (iid))
+- return;
+-
+ frame = g_object_new (PANEL_TYPE_APPLET_FRAME, NULL);
+ frame->priv->panel = panel;
+ frame->priv->iid = g_strdup (iid);
+@@ -346,15 +345,26 @@
+ frame_act->exactpos = exactpos;
+ frame_act->id = g_strdup (id);
+
+- moniker = panel_applet_frame_construct_moniker (frame, panel, iid, id);
++ /* If the applet is disabled, we don't actually load the bonobo component,
++ but keep the objects around so that, should the disabled state change,
++ we'll be able to reload the applet in its proper state. */
++ if (panel_lockdown_is_applet_disabled (iid)) {
++ panel_applet_frame_activated (NULL, NULL, frame_act);
++ }
++ else {
++ CORBA_Environment ev;
++ char *moniker;
++
++ moniker = panel_applet_frame_construct_moniker (frame, panel, iid, id);
+
+- CORBA_exception_init (&ev);
++ CORBA_exception_init (&ev);
+
+- bonobo_get_object_async (moniker, "IDL:Bonobo/Control:1.0", &ev,
+- (BonoboMonikerAsyncFn) panel_applet_frame_activated,
+- frame_act);
++ bonobo_get_object_async (moniker, "IDL:Bonobo/Control:1.0", &ev,
++ (BonoboMonikerAsyncFn) panel_applet_frame_activated,
++ frame_act);
+
+- g_free (moniker);
++ g_free (moniker);
++ }
+ }
+
+ void
+@@ -405,6 +415,19 @@
+ g_free (id);
+ }
+
++static void panel_applet_frame_reload (PanelAppletFrame *frame);
++
++gboolean
++panel_applet_frame_refresh (PanelAppletFrame *frame)
++{
++ if ((frame->priv->ui_component == NULL) !=
++ panel_lockdown_is_applet_disabled (frame->priv->iid)) {
++ panel_applet_frame_reload (frame);
++ return TRUE;
++ }
++ return FALSE;
++}
++
+ void
+ panel_applet_frame_change_orientation (PanelAppletFrame *frame,
+ PanelOrientation orientation)
+@@ -847,6 +870,33 @@
+ return handled;
+ }
+
++static void
++panel_applet_frame_reload (PanelAppletFrame *frame)
++{
++ PanelWidget *panel;
++ char *iid;
++ char *id = NULL;
++ int position = -1;
++ gboolean locked = FALSE;
++ AppletInfo *info = NULL;
++
++ info = frame->priv->applet_info;
++ panel = frame->priv->panel;
++ iid = g_strdup (frame->priv->iid);
++
++ if (info) {
++ id = g_strdup (info->id);
++ position = panel_applet_get_position (info);
++ locked = panel_widget_get_applet_locked (panel, info->widget);
++ panel_applet_clean (info);
++ }
++
++ panel_applet_frame_load (iid, panel, locked, position, TRUE, id);
++
++ g_free (iid);
++ g_free (id);
++}
++
+ static void
+ panel_applet_frame_reload_response (GtkWidget *dialog,
+ int response,
+@@ -862,28 +912,7 @@
+ info = frame->priv->applet_info;
+
+ if (response == GTK_RESPONSE_YES) {
+- PanelWidget *panel;
+- char *iid;
+- char *id = NULL;
+- int position = -1;
+- gboolean locked = FALSE;
+-
+- panel = frame->priv->panel;
+- iid = g_strdup (frame->priv->iid);
+-
+- if (info) {
+- id = g_strdup (info->id);
+- position = panel_applet_get_position (info);
+- locked = panel_widget_get_applet_locked (panel, info->widget);
+- panel_applet_clean (info);
+- }
+-
+- panel_applet_frame_load (iid, panel, locked,
+- position, TRUE, id);
+-
+- g_free (iid);
+- g_free (id);
+-
++ panel_applet_frame_reload (frame);
+ } else if (info) {
+ /* if we can't write to applets list we can't really delete
+ it, so we'll just ignore this. FIXME: handle this
+@@ -1257,129 +1286,135 @@
+ frame_act = (PanelAppletFrameActivating *) data;
+ frame = frame_act->frame;
+
+- /* according to the source of bonobo control == NULL && no
+- exception can happen, so handle it */
+- if (BONOBO_EX (ev) || object == CORBA_OBJECT_NIL) {
+- error = bonobo_exception_get_text (ev);
+- g_warning (G_STRLOC ": failed to load applet %s:\n%s",
+- frame->priv->iid, error);
+- panel_applet_frame_loading_failed (frame, frame_act->id);
+- g_free (frame_act->id);
+- g_free (frame_act);
+- g_free (error);
+- return;
+- }
++ if (ev != NULL) {
++ /* Case where we end up here as a result of actually loading the
++ component. */
++ /* according to the source of bonobo control == NULL && no
++ exception can happen, so handle it */
++ if (BONOBO_EX (ev) || object == CORBA_OBJECT_NIL) {
++ error = bonobo_exception_get_text (ev);
++ g_warning (G_STRLOC ": failed to load applet %s:\n%s",
++ frame->priv->iid, error);
++ panel_applet_frame_loading_failed (frame, frame_act->id);
++ g_free (frame_act->id);
++ g_free (frame_act);
++ g_free (error);
++ return;
++ }
+
+- frame->priv->control = CORBA_Object_duplicate (object, NULL);
++ frame->priv->control = CORBA_Object_duplicate (object, NULL);
+
+- widget = bonobo_widget_new_control_from_objref (object,
+- CORBA_OBJECT_NIL);
++ widget = bonobo_widget_new_control_from_objref (object,
++ CORBA_OBJECT_NIL);
+
+- bonobo_object_release_unref (object, NULL);
++ bonobo_object_release_unref (object, NULL);
+
+- if (!widget) {
+- g_warning (G_STRLOC ": failed to load applet %s",
+- frame->priv->iid);
+- panel_applet_frame_loading_failed (frame, frame_act->id);
+- g_free (frame_act->id);
+- g_free (frame_act);
+- return;
+- }
+-
+- control_frame = bonobo_widget_get_control_frame (BONOBO_WIDGET (widget));
+- if (control_frame == NULL) {
+- g_warning (G_STRLOC ": failed to load applet %s "
+- "(cannot get control frame)", frame->priv->iid);
+- panel_applet_frame_loading_failed (frame, frame_act->id);
+- gtk_object_sink (GTK_OBJECT (widget));
+- g_free (frame_act->id);
+- g_free (frame_act);
+- return;
+- }
++ if (!widget) {
++ g_warning (G_STRLOC ": failed to load applet %s",
++ frame->priv->iid);
++ panel_applet_frame_loading_failed (frame, frame_act->id);
++ g_free (frame_act->id);
++ g_free (frame_act);
++ return;
++ }
+
+- frame->priv->property_bag =
+- bonobo_control_frame_get_control_property_bag (control_frame,
+- &corba_ev);
+- if (frame->priv->property_bag == NULL || BONOBO_EX (&corba_ev)) {
+- error = bonobo_exception_get_text (&corba_ev);
+- CORBA_exception_free (&corba_ev);
+- g_warning (G_STRLOC ": failed to load applet %s "
+- "(cannot get property bag):\n%s",
+- frame->priv->iid, error);
+- panel_applet_frame_loading_failed (frame, frame_act->id);
+- gtk_object_sink (GTK_OBJECT (widget));
+- g_free (frame_act->id);
+- g_free (frame_act);
+- g_free (error);
+- return;
+- }
++ control_frame = bonobo_widget_get_control_frame (BONOBO_WIDGET (widget));
++ if (control_frame == NULL) {
++ g_warning (G_STRLOC ": failed to load applet %s "
++ "(can't get control frame)", frame->priv->iid);
++ panel_applet_frame_loading_failed (frame, frame_act->id);
++ gtk_object_sink (GTK_OBJECT (widget));
++ g_free (frame_act->id);
++ g_free (frame_act);
++ return;
++ }
+
+- bonobo_event_source_client_add_listener (frame->priv->property_bag,
+- (BonoboListenerCallbackFn) panel_applet_frame_event_listener,
+- "Bonobo/Property:change:panel-applet",
+- NULL,
+- frame);
++ frame->priv->property_bag =
++ bonobo_control_frame_get_control_property_bag (control_frame,
++ &corba_ev);
++ if (frame->priv->property_bag == NULL || BONOBO_EX (&corba_ev)) {
++ error = bonobo_exception_get_text (&corba_ev);
++ CORBA_exception_free (&corba_ev);
++ g_warning (G_STRLOC ": failed to load applet %s "
++ "(can't get property bag):\n%s",
++ frame->priv->iid, error);
++ panel_applet_frame_loading_failed (frame, frame_act->id);
++ gtk_object_sink (GTK_OBJECT (widget));
++ g_free (frame_act->id);
++ g_free (frame_act);
++ g_free (error);
++ return;
++ }
++
++ bonobo_event_source_client_add_listener (frame->priv->property_bag,
++ (BonoboListenerCallbackFn) panel_applet_frame_event_listener,
++ "Bonobo/Property:change:panel-applet",
++ NULL,
++ frame);
+
+- frame->priv->ui_component =
+- bonobo_control_frame_get_popup_component (control_frame,
+- &corba_ev);
+- if (frame->priv->ui_component == NULL || BONOBO_EX (&corba_ev)) {
+- error = bonobo_exception_get_text (&corba_ev);
+- CORBA_exception_free (&corba_ev);
+- g_warning (G_STRLOC ": failed to load applet %s "
+- "(cannot get popup component):\n%s",
+- frame->priv->iid, error);
+- panel_applet_frame_loading_failed (frame, frame_act->id);
+- gtk_object_sink (GTK_OBJECT (widget));
+- g_free (frame_act->id);
+- g_free (frame_act);
+- g_free (error);
+- return;
+- }
+-
+- bonobo_ui_util_set_ui (frame->priv->ui_component, DATADIR,
+- "GNOME_Panel_Popup.xml", "panel", NULL);
+-
+- bonobo_ui_component_add_listener (frame->priv->ui_component,
+- "LockAppletToPanel",
+- listener_popup_handle_lock,
+- frame);
+-
+- bonobo_ui_component_add_verb_list_with_data (
+- frame->priv->ui_component, popup_verbs, frame);
+-
+- control = bonobo_control_frame_get_control (control_frame);
+- if (!control) {
+- CORBA_exception_free (&corba_ev);
+- g_warning (G_STRLOC ": failed to load applet %s "
+- "(cannot get control)", frame->priv->iid);
+- panel_applet_frame_loading_failed (frame, frame_act->id);
+- gtk_object_sink (GTK_OBJECT (widget));
+- g_free (frame_act->id);
+- g_free (frame_act);
+- return;
+- }
+-
+- frame->priv->applet_shell = panel_applet_frame_get_applet_shell (control);
+- if (frame->priv->applet_shell == CORBA_OBJECT_NIL) {
+- CORBA_exception_free (&corba_ev);
+- g_warning (G_STRLOC ": failed to load applet %s "
+- "(cannot get applet shell)", frame->priv->iid);
+- panel_applet_frame_loading_failed (frame, frame_act->id);
+- gtk_object_sink (GTK_OBJECT (widget));
+- g_free (frame_act->id);
+- g_free (frame_act);
+- return;
+- }
+-
+- CORBA_exception_free (&corba_ev);
+-
+- ORBit_small_listen_for_broken (object,
+- G_CALLBACK (panel_applet_frame_cnx_broken),
+- frame);
++ frame->priv->ui_component =
++ bonobo_control_frame_get_popup_component (control_frame,
++ &corba_ev);
++ if (frame->priv->ui_component == NULL || BONOBO_EX (&corba_ev)) {
++ error = bonobo_exception_get_text (&corba_ev);
++ CORBA_exception_free (&corba_ev);
++ g_warning (G_STRLOC ": failed to load applet %s "
++ "(can't get popup component):\n%s",
++ frame->priv->iid, error);
++ panel_applet_frame_loading_failed (frame, frame_act->id);
++ gtk_object_sink (GTK_OBJECT (widget));
++ g_free (frame_act->id);
++ g_free (frame_act);
++ g_free (error);
++ return;
++ }
++
++ bonobo_ui_util_set_ui (frame->priv->ui_component, DATADIR,
++ "GNOME_Panel_Popup.xml", "panel", NULL);
++
++ bonobo_ui_component_add_listener (frame->priv->ui_component,
++ "LockAppletToPanel",
++ listener_popup_handle_lock,
++ frame);
++
++ bonobo_ui_component_add_verb_list_with_data (
++ frame->priv->ui_component, popup_verbs, frame);
++
++ control = bonobo_control_frame_get_control (control_frame);
++ if (!control) {
++ CORBA_exception_free (&corba_ev);
++ g_warning (G_STRLOC ": failed to load applet %s "
++ "(can't get control)", frame->priv->iid);
++ panel_applet_frame_loading_failed (frame, frame_act->id);
++ gtk_object_sink (GTK_OBJECT (widget));
++ g_free (frame_act->id);
++ g_free (frame_act);
++ return;
++ }
++
++ frame->priv->applet_shell = panel_applet_frame_get_applet_shell (control);
++ if (frame->priv->applet_shell == CORBA_OBJECT_NIL) {
++ CORBA_exception_free (&corba_ev);
++ g_warning (G_STRLOC ": failed to load applet %s "
++ "(can't get applet shell)", frame->priv->iid);
++ panel_applet_frame_loading_failed (frame, frame_act->id);
++ gtk_object_sink (GTK_OBJECT (widget));
++ g_free (frame_act->id);
++ g_free (frame_act);
++ return;
++ }
++
++ CORBA_exception_free (&corba_ev);
++
++ ORBit_small_listen_for_broken (object,
++ G_CALLBACK (panel_applet_frame_cnx_broken),
++ frame);
+
+- gtk_container_add (GTK_CONTAINER (frame), widget);
++ gtk_container_add (GTK_CONTAINER (frame), widget);
++ }
+
++ /* Regardless of whether the object was actually loaded, the corresponding
++ applet is created to handle lockdown state changes. */
+ gtk_widget_show_all (GTK_WIDGET (frame));
+
+ info = panel_applet_register (GTK_WIDGET (frame), GTK_WIDGET (frame),
+--- gnome-panel-2.15.91.old/gnome-panel/applet.c 2006-08-09 15:43:31.121253000 +0100
++++ gnome-panel-2.15.91/gnome-panel/applet.c 2006-08-09 15:46:33.259175000 +0100
+@@ -159,6 +159,31 @@
+ info->menu = panel_applet_create_menu (info);
+ }
+
++static void panel_applet_check_visibility(AppletInfo *info)
++{
++ if (info->type == PANEL_OBJECT_LAUNCHER) {
++ if (panel_lockdown_is_forbidden_launcher (info->data)) {
++ gtk_widget_hide(info->widget) ;
++ }
++ else { gtk_widget_show(info->widget) ; }
++ }
++}
++
++static void panel_applet_refresh_state(AppletInfo *info)
++{
++ if (info->type == PANEL_OBJECT_BONOBO) {
++ if (!panel_applet_frame_refresh(info->data)) {
++ /* If the applet frame was rebuilt, no point in
++ recreating the menu. */
++ panel_applet_recreate_menu(info) ;
++ }
++ }
++ else {
++ panel_applet_check_visibility(info) ;
++ panel_applet_recreate_menu(info) ;
++ }
++}
++
+ static void
+ panel_applet_locked_change_notify (GConfClient *client,
+ guint cnxn_id,
+@@ -738,8 +763,7 @@
+ }
+ }
+
+- if (info->type != PANEL_OBJECT_BONOBO)
+- panel_lockdown_notify_remove (G_CALLBACK (panel_applet_recreate_menu),
++ panel_lockdown_notify_remove (G_CALLBACK (panel_applet_refresh_state),
+ info);
+
+ if (info->menu)
+@@ -1182,8 +1206,7 @@
+
+ g_object_set_data (G_OBJECT (applet), "applet_info", info);
+
+- if (type != PANEL_OBJECT_BONOBO)
+- panel_lockdown_notify_add (G_CALLBACK (panel_applet_recreate_menu),
++ panel_lockdown_notify_add (G_CALLBACK (panel_applet_refresh_state),
+ info);
+
+ key = panel_gconf_full_key ((type == PANEL_OBJECT_BONOBO) ?
--- a/patches/gnome-panel-13-noswitchuser.diff Fri Oct 20 15:24:25 2006 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
---- gnome-panel-2.14.1/gnome-panel/panel-logout.c-orig 2006-07-13 18:01:22.906575000 -0500
-+++ gnome-panel-2.14.1/gnome-panel/panel-logout.c 2006-07-13 18:01:53.050421000 -0500
-@@ -304,9 +304,13 @@ panel_logout_new (PanelLogoutDialogType
- logout_dialog->priv->default_response = PANEL_LOGOUT_DIALOG_LOGOUT;
-
- //FIXME is gdm running?
-+/*
-+ * Comment "Switch User" button until VT's are supported on Solaris
-+ *
- gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
- _("_Switch User"),
- PANEL_LOGOUT_RESPONSE_SWITCH_USER);
-+*/
- gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
- GTK_STOCK_CANCEL,
- GTK_RESPONSE_CANCEL);
--- a/patches/gnome-panel-14-lockdown-applets.diff Fri Oct 20 15:24:25 2006 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,469 +0,0 @@
---- gnome-panel-2.15.91.old/gnome-panel/panel-applet-frame.h 2006-08-09 15:43:31.452059000 +0100
-+++ gnome-panel-2.15.91/gnome-panel/panel-applet-frame.h 2006-08-09 16:37:36.089721000 +0100
-@@ -78,6 +78,14 @@
- void panel_applet_frame_set_panel (PanelAppletFrame *frame,
- PanelWidget *panel);
-
-+/**
-+ * Checks whether the applet has been disabled or reenabled and if necessary
-+ * rebuilds the applet.
-+ * Returns true if the applet frame was rebuilt as a result of its restriction
-+ * status changing.
-+ */
-+gboolean panel_applet_frame_refresh (PanelAppletFrame *frame);
-+
- G_END_DECLS
-
- #endif /* __PANEL_APPLET_FRAME_H__ */
---- gnome-panel-2.15.91.old/gnome-panel/panel-applet-frame.c 2006-08-09 15:43:31.125609000 +0100
-+++ gnome-panel-2.15.91/gnome-panel/panel-applet-frame.c 2006-08-09 17:55:28.281987000 +0100
-@@ -116,6 +116,10 @@
- gboolean movable;
- gboolean removable;
-
-+ /* If the applet is currently in a disabled state, no need for a menu */
-+ if (frame->priv->ui_component == NULL)
-+ return;
-+
- panel_widget = PANEL_WIDGET (GTK_WIDGET (frame)->parent);
-
- lockable = panel_applet_lockable (frame->priv->applet_info);
-@@ -324,17 +328,12 @@
- const char *id)
- {
- PanelAppletFrame *frame;
-- CORBA_Environment ev;
-- char *moniker;
- PanelAppletFrameActivating *frame_act;
-
- g_return_if_fail (iid != NULL);
- g_return_if_fail (panel != NULL);
- g_return_if_fail (id != NULL);
-
-- if (panel_lockdown_is_applet_disabled (iid))
-- return;
--
- frame = g_object_new (PANEL_TYPE_APPLET_FRAME, NULL);
- frame->priv->panel = panel;
- frame->priv->iid = g_strdup (iid);
-@@ -346,15 +345,26 @@
- frame_act->exactpos = exactpos;
- frame_act->id = g_strdup (id);
-
-- moniker = panel_applet_frame_construct_moniker (frame, panel, iid, id);
-+ /* If the applet is disabled, we don't actually load the bonobo component,
-+ but keep the objects around so that, should the disabled state change,
-+ we'll be able to reload the applet in its proper state. */
-+ if (panel_lockdown_is_applet_disabled (iid)) {
-+ panel_applet_frame_activated (NULL, NULL, frame_act);
-+ }
-+ else {
-+ CORBA_Environment ev;
-+ char *moniker;
-+
-+ moniker = panel_applet_frame_construct_moniker (frame, panel, iid, id);
-
-- CORBA_exception_init (&ev);
-+ CORBA_exception_init (&ev);
-
-- bonobo_get_object_async (moniker, "IDL:Bonobo/Control:1.0", &ev,
-- (BonoboMonikerAsyncFn) panel_applet_frame_activated,
-- frame_act);
-+ bonobo_get_object_async (moniker, "IDL:Bonobo/Control:1.0", &ev,
-+ (BonoboMonikerAsyncFn) panel_applet_frame_activated,
-+ frame_act);
-
-- g_free (moniker);
-+ g_free (moniker);
-+ }
- }
-
- void
-@@ -405,6 +415,19 @@
- g_free (id);
- }
-
-+static void panel_applet_frame_reload (PanelAppletFrame *frame);
-+
-+gboolean
-+panel_applet_frame_refresh (PanelAppletFrame *frame)
-+{
-+ if ((frame->priv->ui_component == NULL) !=
-+ panel_lockdown_is_applet_disabled (frame->priv->iid)) {
-+ panel_applet_frame_reload (frame);
-+ return TRUE;
-+ }
-+ return FALSE;
-+}
-+
- void
- panel_applet_frame_change_orientation (PanelAppletFrame *frame,
- PanelOrientation orientation)
-@@ -847,6 +870,33 @@
- return handled;
- }
-
-+static void
-+panel_applet_frame_reload (PanelAppletFrame *frame)
-+{
-+ PanelWidget *panel;
-+ char *iid;
-+ char *id = NULL;
-+ int position = -1;
-+ gboolean locked = FALSE;
-+ AppletInfo *info = NULL;
-+
-+ info = frame->priv->applet_info;
-+ panel = frame->priv->panel;
-+ iid = g_strdup (frame->priv->iid);
-+
-+ if (info) {
-+ id = g_strdup (info->id);
-+ position = panel_applet_get_position (info);
-+ locked = panel_widget_get_applet_locked (panel, info->widget);
-+ panel_applet_clean (info);
-+ }
-+
-+ panel_applet_frame_load (iid, panel, locked, position, TRUE, id);
-+
-+ g_free (iid);
-+ g_free (id);
-+}
-+
- static void
- panel_applet_frame_reload_response (GtkWidget *dialog,
- int response,
-@@ -862,28 +912,7 @@
- info = frame->priv->applet_info;
-
- if (response == GTK_RESPONSE_YES) {
-- PanelWidget *panel;
-- char *iid;
-- char *id = NULL;
-- int position = -1;
-- gboolean locked = FALSE;
--
-- panel = frame->priv->panel;
-- iid = g_strdup (frame->priv->iid);
--
-- if (info) {
-- id = g_strdup (info->id);
-- position = panel_applet_get_position (info);
-- locked = panel_widget_get_applet_locked (panel, info->widget);
-- panel_applet_clean (info);
-- }
--
-- panel_applet_frame_load (iid, panel, locked,
-- position, TRUE, id);
--
-- g_free (iid);
-- g_free (id);
--
-+ panel_applet_frame_reload (frame);
- } else if (info) {
- /* if we can't write to applets list we can't really delete
- it, so we'll just ignore this. FIXME: handle this
-@@ -1257,129 +1286,135 @@
- frame_act = (PanelAppletFrameActivating *) data;
- frame = frame_act->frame;
-
-- /* according to the source of bonobo control == NULL && no
-- exception can happen, so handle it */
-- if (BONOBO_EX (ev) || object == CORBA_OBJECT_NIL) {
-- error = bonobo_exception_get_text (ev);
-- g_warning (G_STRLOC ": failed to load applet %s:\n%s",
-- frame->priv->iid, error);
-- panel_applet_frame_loading_failed (frame, frame_act->id);
-- g_free (frame_act->id);
-- g_free (frame_act);
-- g_free (error);
-- return;
-- }
-+ if (ev != NULL) {
-+ /* Case where we end up here as a result of actually loading the
-+ component. */
-+ /* according to the source of bonobo control == NULL && no
-+ exception can happen, so handle it */
-+ if (BONOBO_EX (ev) || object == CORBA_OBJECT_NIL) {
-+ error = bonobo_exception_get_text (ev);
-+ g_warning (G_STRLOC ": failed to load applet %s:\n%s",
-+ frame->priv->iid, error);
-+ panel_applet_frame_loading_failed (frame, frame_act->id);
-+ g_free (frame_act->id);
-+ g_free (frame_act);
-+ g_free (error);
-+ return;
-+ }
-
-- frame->priv->control = CORBA_Object_duplicate (object, NULL);
-+ frame->priv->control = CORBA_Object_duplicate (object, NULL);
-
-- widget = bonobo_widget_new_control_from_objref (object,
-- CORBA_OBJECT_NIL);
-+ widget = bonobo_widget_new_control_from_objref (object,
-+ CORBA_OBJECT_NIL);
-
-- bonobo_object_release_unref (object, NULL);
-+ bonobo_object_release_unref (object, NULL);
-
-- if (!widget) {
-- g_warning (G_STRLOC ": failed to load applet %s",
-- frame->priv->iid);
-- panel_applet_frame_loading_failed (frame, frame_act->id);
-- g_free (frame_act->id);
-- g_free (frame_act);
-- return;
-- }
--
-- control_frame = bonobo_widget_get_control_frame (BONOBO_WIDGET (widget));
-- if (control_frame == NULL) {
-- g_warning (G_STRLOC ": failed to load applet %s "
-- "(cannot get control frame)", frame->priv->iid);
-- panel_applet_frame_loading_failed (frame, frame_act->id);
-- gtk_object_sink (GTK_OBJECT (widget));
-- g_free (frame_act->id);
-- g_free (frame_act);
-- return;
-- }
-+ if (!widget) {
-+ g_warning (G_STRLOC ": failed to load applet %s",
-+ frame->priv->iid);
-+ panel_applet_frame_loading_failed (frame, frame_act->id);
-+ g_free (frame_act->id);
-+ g_free (frame_act);
-+ return;
-+ }
-
-- frame->priv->property_bag =
-- bonobo_control_frame_get_control_property_bag (control_frame,
-- &corba_ev);
-- if (frame->priv->property_bag == NULL || BONOBO_EX (&corba_ev)) {
-- error = bonobo_exception_get_text (&corba_ev);
-- CORBA_exception_free (&corba_ev);
-- g_warning (G_STRLOC ": failed to load applet %s "
-- "(cannot get property bag):\n%s",
-- frame->priv->iid, error);
-- panel_applet_frame_loading_failed (frame, frame_act->id);
-- gtk_object_sink (GTK_OBJECT (widget));
-- g_free (frame_act->id);
-- g_free (frame_act);
-- g_free (error);
-- return;
-- }
-+ control_frame = bonobo_widget_get_control_frame (BONOBO_WIDGET (widget));
-+ if (control_frame == NULL) {
-+ g_warning (G_STRLOC ": failed to load applet %s "
-+ "(can't get control frame)", frame->priv->iid);
-+ panel_applet_frame_loading_failed (frame, frame_act->id);
-+ gtk_object_sink (GTK_OBJECT (widget));
-+ g_free (frame_act->id);
-+ g_free (frame_act);
-+ return;
-+ }
-
-- bonobo_event_source_client_add_listener (frame->priv->property_bag,
-- (BonoboListenerCallbackFn) panel_applet_frame_event_listener,
-- "Bonobo/Property:change:panel-applet",
-- NULL,
-- frame);
-+ frame->priv->property_bag =
-+ bonobo_control_frame_get_control_property_bag (control_frame,
-+ &corba_ev);
-+ if (frame->priv->property_bag == NULL || BONOBO_EX (&corba_ev)) {
-+ error = bonobo_exception_get_text (&corba_ev);
-+ CORBA_exception_free (&corba_ev);
-+ g_warning (G_STRLOC ": failed to load applet %s "
-+ "(can't get property bag):\n%s",
-+ frame->priv->iid, error);
-+ panel_applet_frame_loading_failed (frame, frame_act->id);
-+ gtk_object_sink (GTK_OBJECT (widget));
-+ g_free (frame_act->id);
-+ g_free (frame_act);
-+ g_free (error);
-+ return;
-+ }
-+
-+ bonobo_event_source_client_add_listener (frame->priv->property_bag,
-+ (BonoboListenerCallbackFn) panel_applet_frame_event_listener,
-+ "Bonobo/Property:change:panel-applet",
-+ NULL,
-+ frame);
-
-- frame->priv->ui_component =
-- bonobo_control_frame_get_popup_component (control_frame,
-- &corba_ev);
-- if (frame->priv->ui_component == NULL || BONOBO_EX (&corba_ev)) {
-- error = bonobo_exception_get_text (&corba_ev);
-- CORBA_exception_free (&corba_ev);
-- g_warning (G_STRLOC ": failed to load applet %s "
-- "(cannot get popup component):\n%s",
-- frame->priv->iid, error);
-- panel_applet_frame_loading_failed (frame, frame_act->id);
-- gtk_object_sink (GTK_OBJECT (widget));
-- g_free (frame_act->id);
-- g_free (frame_act);
-- g_free (error);
-- return;
-- }
--
-- bonobo_ui_util_set_ui (frame->priv->ui_component, DATADIR,
-- "GNOME_Panel_Popup.xml", "panel", NULL);
--
-- bonobo_ui_component_add_listener (frame->priv->ui_component,
-- "LockAppletToPanel",
-- listener_popup_handle_lock,
-- frame);
--
-- bonobo_ui_component_add_verb_list_with_data (
-- frame->priv->ui_component, popup_verbs, frame);
--
-- control = bonobo_control_frame_get_control (control_frame);
-- if (!control) {
-- CORBA_exception_free (&corba_ev);
-- g_warning (G_STRLOC ": failed to load applet %s "
-- "(cannot get control)", frame->priv->iid);
-- panel_applet_frame_loading_failed (frame, frame_act->id);
-- gtk_object_sink (GTK_OBJECT (widget));
-- g_free (frame_act->id);
-- g_free (frame_act);
-- return;
-- }
--
-- frame->priv->applet_shell = panel_applet_frame_get_applet_shell (control);
-- if (frame->priv->applet_shell == CORBA_OBJECT_NIL) {
-- CORBA_exception_free (&corba_ev);
-- g_warning (G_STRLOC ": failed to load applet %s "
-- "(cannot get applet shell)", frame->priv->iid);
-- panel_applet_frame_loading_failed (frame, frame_act->id);
-- gtk_object_sink (GTK_OBJECT (widget));
-- g_free (frame_act->id);
-- g_free (frame_act);
-- return;
-- }
--
-- CORBA_exception_free (&corba_ev);
--
-- ORBit_small_listen_for_broken (object,
-- G_CALLBACK (panel_applet_frame_cnx_broken),
-- frame);
-+ frame->priv->ui_component =
-+ bonobo_control_frame_get_popup_component (control_frame,
-+ &corba_ev);
-+ if (frame->priv->ui_component == NULL || BONOBO_EX (&corba_ev)) {
-+ error = bonobo_exception_get_text (&corba_ev);
-+ CORBA_exception_free (&corba_ev);
-+ g_warning (G_STRLOC ": failed to load applet %s "
-+ "(can't get popup component):\n%s",
-+ frame->priv->iid, error);
-+ panel_applet_frame_loading_failed (frame, frame_act->id);
-+ gtk_object_sink (GTK_OBJECT (widget));
-+ g_free (frame_act->id);
-+ g_free (frame_act);
-+ g_free (error);
-+ return;
-+ }
-+
-+ bonobo_ui_util_set_ui (frame->priv->ui_component, DATADIR,
-+ "GNOME_Panel_Popup.xml", "panel", NULL);
-+
-+ bonobo_ui_component_add_listener (frame->priv->ui_component,
-+ "LockAppletToPanel",
-+ listener_popup_handle_lock,
-+ frame);
-+
-+ bonobo_ui_component_add_verb_list_with_data (
-+ frame->priv->ui_component, popup_verbs, frame);
-+
-+ control = bonobo_control_frame_get_control (control_frame);
-+ if (!control) {
-+ CORBA_exception_free (&corba_ev);
-+ g_warning (G_STRLOC ": failed to load applet %s "
-+ "(can't get control)", frame->priv->iid);
-+ panel_applet_frame_loading_failed (frame, frame_act->id);
-+ gtk_object_sink (GTK_OBJECT (widget));
-+ g_free (frame_act->id);
-+ g_free (frame_act);
-+ return;
-+ }
-+
-+ frame->priv->applet_shell = panel_applet_frame_get_applet_shell (control);
-+ if (frame->priv->applet_shell == CORBA_OBJECT_NIL) {
-+ CORBA_exception_free (&corba_ev);
-+ g_warning (G_STRLOC ": failed to load applet %s "
-+ "(can't get applet shell)", frame->priv->iid);
-+ panel_applet_frame_loading_failed (frame, frame_act->id);
-+ gtk_object_sink (GTK_OBJECT (widget));
-+ g_free (frame_act->id);
-+ g_free (frame_act);
-+ return;
-+ }
-+
-+ CORBA_exception_free (&corba_ev);
-+
-+ ORBit_small_listen_for_broken (object,
-+ G_CALLBACK (panel_applet_frame_cnx_broken),
-+ frame);
-
-- gtk_container_add (GTK_CONTAINER (frame), widget);
-+ gtk_container_add (GTK_CONTAINER (frame), widget);
-+ }
-
-+ /* Regardless of whether the object was actually loaded, the corresponding
-+ applet is created to handle lockdown state changes. */
- gtk_widget_show_all (GTK_WIDGET (frame));
-
- info = panel_applet_register (GTK_WIDGET (frame), GTK_WIDGET (frame),
---- gnome-panel-2.15.91.old/gnome-panel/applet.c 2006-08-09 15:43:31.121253000 +0100
-+++ gnome-panel-2.15.91/gnome-panel/applet.c 2006-08-09 15:46:33.259175000 +0100
-@@ -159,6 +159,31 @@
- info->menu = panel_applet_create_menu (info);
- }
-
-+static void panel_applet_check_visibility(AppletInfo *info)
-+{
-+ if (info->type == PANEL_OBJECT_LAUNCHER) {
-+ if (panel_lockdown_is_forbidden_launcher (info->data)) {
-+ gtk_widget_hide(info->widget) ;
-+ }
-+ else { gtk_widget_show(info->widget) ; }
-+ }
-+}
-+
-+static void panel_applet_refresh_state(AppletInfo *info)
-+{
-+ if (info->type == PANEL_OBJECT_BONOBO) {
-+ if (!panel_applet_frame_refresh(info->data)) {
-+ /* If the applet frame was rebuilt, no point in
-+ recreating the menu. */
-+ panel_applet_recreate_menu(info) ;
-+ }
-+ }
-+ else {
-+ panel_applet_check_visibility(info) ;
-+ panel_applet_recreate_menu(info) ;
-+ }
-+}
-+
- static void
- panel_applet_locked_change_notify (GConfClient *client,
- guint cnxn_id,
-@@ -738,8 +763,7 @@
- }
- }
-
-- if (info->type != PANEL_OBJECT_BONOBO)
-- panel_lockdown_notify_remove (G_CALLBACK (panel_applet_recreate_menu),
-+ panel_lockdown_notify_remove (G_CALLBACK (panel_applet_refresh_state),
- info);
-
- if (info->menu)
-@@ -1182,8 +1206,7 @@
-
- g_object_set_data (G_OBJECT (applet), "applet_info", info);
-
-- if (type != PANEL_OBJECT_BONOBO)
-- panel_lockdown_notify_add (G_CALLBACK (panel_applet_recreate_menu),
-+ panel_lockdown_notify_add (G_CALLBACK (panel_applet_refresh_state),
- info);
-
- key = panel_gconf_full_key ((type == PANEL_OBJECT_BONOBO) ?
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/gnome-panel-14-support-alacarte.diff Fri Oct 20 15:31:04 2006 +0000
@@ -0,0 +1,36 @@
+diff -ur gnome-panel-2.15.91/gnome-panel/panel-menu-button.c gnome-panel-2.15.91-hack/gnome-panel/panel-menu-button.c
+--- gnome-panel-2.15.91/gnome-panel/panel-menu-button.c 2006-08-16 12:56:21.848819000 +0800
++++ gnome-panel-2.15.91-hack/gnome-panel/panel-menu-button.c 2006-08-16 13:48:22.680824000 +0800
+@@ -406,8 +406,17 @@
+ PanelMenuButton *button)
+ {
+ if (button->priv->menu) {
++ GMenuTree *tree;
++
+ gtk_widget_destroy (GTK_WIDGET (button->priv->menu));
+ panel_menu_button_create_menu (button);
++#if defined(sun) && defined(__SVR4)
++ /* force a reload of the menu tree as Solaris doesn't support FAM*/
++ if ((tree = g_object_get_data (G_OBJECT (button->priv->menu),
++ "panel-menu-tree"))) {
++ gmenu_tree_force_reload (tree);
++ }
++#endif
+ }
+ }
+
+@@ -715,6 +724,14 @@
+ (GConfClientNotifyFunc) panel_menu_button_reload_menus,
+ G_OBJECT (button));
+
++#if defined(sun) && defined(__SVR4)
++#define MENU_TREE_RELOAD_KEY "/apps/panel/general/menu_tree_reload"
++
++ panel_gconf_notify_add_while_alive (MENU_TREE_RELOAD_KEY,
++ (GConfClientNotifyFunc) panel_menu_button_reload_menus,
++ G_OBJECT (button));
++#endif
++
+ }
+
+ static char *
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/gnome-panel-15-lXau.diff Fri Oct 20 15:31:04 2006 +0000
@@ -0,0 +1,10 @@
+--- gnome-panel-2.15.92.old/configure.in 2006-08-23 10:44:19.575470000 +0100
++++ gnome-panel-2.15.92/configure.in 2006-08-23 10:45:37.800195000 +0100
+@@ -211,6 +211,7 @@
+ AC_MSG_ERROR([X development libraries not found])
+ else
+ X_LIBS="$X_PRE_LIBS $X_LIBS -lX11 $X_EXTRA_LIBS"
++ AC_CHECK_LIB(Xau, XauFileName, [X_LIBS="$X_LIBS -lXau"])
+ fi
+ fi
+
--- a/patches/gnome-panel-15-support-alacarte.diff Fri Oct 20 15:24:25 2006 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-diff -ur gnome-panel-2.15.91/gnome-panel/panel-menu-button.c gnome-panel-2.15.91-hack/gnome-panel/panel-menu-button.c
---- gnome-panel-2.15.91/gnome-panel/panel-menu-button.c 2006-08-16 12:56:21.848819000 +0800
-+++ gnome-panel-2.15.91-hack/gnome-panel/panel-menu-button.c 2006-08-16 13:48:22.680824000 +0800
-@@ -406,8 +406,17 @@
- PanelMenuButton *button)
- {
- if (button->priv->menu) {
-+ GMenuTree *tree;
-+
- gtk_widget_destroy (GTK_WIDGET (button->priv->menu));
- panel_menu_button_create_menu (button);
-+#if defined(sun) && defined(__SVR4)
-+ /* force a reload of the menu tree as Solaris doesn't support FAM*/
-+ if ((tree = g_object_get_data (G_OBJECT (button->priv->menu),
-+ "panel-menu-tree"))) {
-+ gmenu_tree_force_reload (tree);
-+ }
-+#endif
- }
- }
-
-@@ -715,6 +724,14 @@
- (GConfClientNotifyFunc) panel_menu_button_reload_menus,
- G_OBJECT (button));
-
-+#if defined(sun) && defined(__SVR4)
-+#define MENU_TREE_RELOAD_KEY "/apps/panel/general/menu_tree_reload"
-+
-+ panel_gconf_notify_add_while_alive (MENU_TREE_RELOAD_KEY,
-+ (GConfClientNotifyFunc) panel_menu_button_reload_menus,
-+ G_OBJECT (button));
-+#endif
-+
- }
-
- static char *
--- a/patches/gnome-panel-16-lXau.diff Fri Oct 20 15:24:25 2006 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
---- gnome-panel-2.15.92.old/configure.in 2006-08-23 10:44:19.575470000 +0100
-+++ gnome-panel-2.15.92/configure.in 2006-08-23 10:45:37.800195000 +0100
-@@ -211,6 +211,7 @@
- AC_MSG_ERROR([X development libraries not found])
- else
- X_LIBS="$X_PRE_LIBS $X_LIBS -lX11 $X_EXTRA_LIBS"
-+ AC_CHECK_LIB(Xau, XauFileName, [X_LIBS="$X_LIBS -lXau"])
- fi
- fi
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/gnome-panel-16-preferences-menu.diff Fri Oct 20 15:31:04 2006 +0000
@@ -0,0 +1,18 @@
+--- gnome-panel-2.16.0/gnome-panel/panel-menu-button.c.orig Mon Oct 2 10:37:33 2006
++++ gnome-panel-2.16.0/gnome-panel/panel-menu-button.c Mon Oct 2 10:55:41 2006
+@@ -57,6 +57,7 @@
+ APPLICATIONS_MENU,
+ #define DEFAULT_MENU APPLICATIONS_MENU
+ SETTINGS_MENU,
++ PREFERENCES_MENU,
+ LAST_MENU
+ } MenuPathRoot;
+
+@@ -68,6 +69,7 @@
+
+ static MenuPathRootItem root_items [] = {
+ { APPLICATIONS_MENU, "applications", "applications.menu" },
++ { PREFERENCES_MENU, "preferences", "preferences.menu" },
+ { SETTINGS_MENU, "settings", "settings.menu" }
+ };
+
--- a/patches/gnome-panel-17-preferences-menu.diff Fri Oct 20 15:24:25 2006 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
---- gnome-panel-2.16.0/gnome-panel/panel-menu-button.c.orig Mon Oct 2 10:37:33 2006
-+++ gnome-panel-2.16.0/gnome-panel/panel-menu-button.c Mon Oct 2 10:55:41 2006
-@@ -57,6 +57,7 @@
- APPLICATIONS_MENU,
- #define DEFAULT_MENU APPLICATIONS_MENU
- SETTINGS_MENU,
-+ PREFERENCES_MENU,
- LAST_MENU
- } MenuPathRoot;
-
-@@ -68,6 +69,7 @@
-
- static MenuPathRootItem root_items [] = {
- { APPLICATIONS_MENU, "applications", "applications.menu" },
-+ { PREFERENCES_MENU, "preferences", "preferences.menu" },
- { SETTINGS_MENU, "settings", "settings.menu" }
- };
-