diff options
| author | Graeme Gregory <dp@xora.org.uk> | 2006-10-30 13:17:22 +0000 |
|---|---|---|
| committer | Graeme Gregory <dp@xora.org.uk> | 2006-10-30 13:17:22 +0000 |
| commit | a7a1382748bd1052bbd8d13fc6c460044b667e35 (patch) | |
| tree | adf43eca87c47466880d0ecdc68b3e9a6982f43e | |
| parent | 9b571a37ba197ba7eaddc0db2ffcb509585fa41a (diff) | |
| parent | e17a0b56f8ad072f9c15ee88a46e6437f85cfa50 (diff) | |
merge of '9176982935d6e1cf409817d2c4c7d9252eeb17f3'
and 'c4b03ec94efc7ce8e9de5522059ec159050d01f2'
19 files changed, 4212 insertions, 0 deletions
diff --git a/packages/gtk+/gtk+-2.10.6/.mtn2git_empty b/packages/gtk+/gtk+-2.10.6/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/packages/gtk+/gtk+-2.10.6/.mtn2git_empty diff --git a/packages/gtk+/gtk+-2.10.6/automake-lossage.patch b/packages/gtk+/gtk+-2.10.6/automake-lossage.patch new file mode 100644 index 0000000000..0d423ddbb9 --- /dev/null +++ b/packages/gtk+/gtk+-2.10.6/automake-lossage.patch @@ -0,0 +1,24 @@ +--- gtk+-2.4.1/docs/tutorial/Makefile.am~ 2003-05-06 22:54:20.000000000 +0100 ++++ gtk+-2.4.1/docs/tutorial/Makefile.am 2004-05-08 12:31:41.000000000 +0100 +@@ -52,21 +52,5 @@ + + dist-hook: html + cp -Rp $(srcdir)/html $(distdir) +-else +-html: +- echo "***" +- echo "*** Warning: Tutorial not built" +- echo "***" +- +-pdf: +- echo "***" +- echo "*** Warning: Tutorial not built" +- echo "***" +- +-dist-hook: +- echo "***" +- echo "*** Warning: Tutorial not built" +- echo "*** DISTRIBUTION IS INCOMPLETE" +- echo "***" + endif + diff --git a/packages/gtk+/gtk+-2.10.6/disable-print.patch b/packages/gtk+/gtk+-2.10.6/disable-print.patch new file mode 100644 index 0000000000..1067773f12 --- /dev/null +++ b/packages/gtk+/gtk+-2.10.6/disable-print.patch @@ -0,0 +1,50 @@ +--- gtk+-2.10.0/configure.in~ 2006-07-05 18:11:44.000000000 +0200 ++++ gtk+-2.10.0/configure.in 2006-07-05 18:11:44.000000000 +0200 +@@ -1539,26 +1539,27 @@ + # Printing system checks + ################################################################ + +-AC_PATH_PROG(CUPS_CONFIG, cups-config, no) +-if test "x$CUPS_CONFIG" != "xno"; then +- CUPS_CFLAGS=`cups-config --cflags | sed 's/-O[0-9]*//' | sed 's/-m[^\t]*//g'` +- CUPS_LIBS=`cups-config --libs` +- +- CUPS_API_VERSION=`cups-config --api-version` +- CUPS_API_MAJOR=`echo -n $CUPS_API_VERSION | awk -F. '{print $1}'` +- CUPS_API_MINOR=`echo -n $CUPS_API_VERSION | awk -F. '{print $2}'` +- +- if test $CUPS_API_MAJOR -gt 1 -o \ +- $CUPS_API_MAJOR -eq 1 -a $CUPS_API_MINOR -ge 2; then +- AC_DEFINE(HAVE_CUPS_API_1_2) +- fi +- +- AC_SUBST(CUPS_API_MAJOR) +- AC_SUBST(CUPS_API_MINOR) +- AC_SUBST(CUPS_CFLAGS) +- AC_SUBST(CUPS_LIBS) +-fi +-AM_CONDITIONAL(HAVE_CUPS, test "x$CUPS_CONFIG" != "xno") ++#AC_PATH_PROG(CUPS_CONFIG, cups-config, no) ++#if test "x$CUPS_CONFIG" != "xno"; then ++# CUPS_CFLAGS=`cups-config --cflags | sed 's/-O[0-9]*//' | sed 's/-m[^\t]*//g'` ++# CUPS_LIBS=`cups-config --libs` ++# ++# CUPS_API_VERSION=`cups-config --api-version` ++# CUPS_API_MAJOR=`echo -n $CUPS_API_VERSION | awk -F. '{print $1}'` ++# CUPS_API_MINOR=`echo -n $CUPS_API_VERSION | awk -F. '{print $2}'` ++# ++# if test $CUPS_API_MAJOR -gt 1 -o \ ++# $CUPS_API_MAJOR -eq 1 -a $CUPS_API_MINOR -ge 2; then ++# AC_DEFINE(HAVE_CUPS_API_1_2) ++# fi ++# ++# AC_SUBST(CUPS_API_MAJOR) ++# AC_SUBST(CUPS_API_MINOR) ++# AC_SUBST(CUPS_CFLAGS) ++# AC_SUBST(CUPS_LIBS) ++#fi ++#AM_CONDITIONAL(HAVE_CUPS, test "x$CUPS_CONFIG" != "xno") ++AM_CONDITIONAL(HAVE_CUPS,false) + + gtk_save_cppflags="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $GTK_DEP_CFLAGS" diff --git a/packages/gtk+/gtk+-2.10.6/disable-tooltips.patch b/packages/gtk+/gtk+-2.10.6/disable-tooltips.patch new file mode 100644 index 0000000000..d71d839c3c --- /dev/null +++ b/packages/gtk+/gtk+-2.10.6/disable-tooltips.patch @@ -0,0 +1,11 @@ +--- gtk+-2.4.3/gtk/gtktooltips.c.old 2004-07-04 18:52:04.000000000 +0100 ++++ gtk+-2.4.3/gtk/gtktooltips.c 2004-07-04 18:52:08.000000000 +0100 +@@ -118,7 +118,7 @@ + tooltips->tips_data_list = NULL; + + tooltips->delay = DEFAULT_DELAY; +- tooltips->enabled = TRUE; ++ tooltips->enabled = FALSE; + tooltips->timer_tag = 0; + tooltips->use_sticky_delay = FALSE; + tooltips->last_popdown.tv_sec = -1; diff --git a/packages/gtk+/gtk+-2.10.6/gtk+-handhelds.patch b/packages/gtk+/gtk+-2.10.6/gtk+-handhelds.patch new file mode 100644 index 0000000000..20481f059b --- /dev/null +++ b/packages/gtk+/gtk+-2.10.6/gtk+-handhelds.patch @@ -0,0 +1,236 @@ +--- gtk+-2.4.1/gtk/gtkarrow.c 2004-03-13 09:51:13.000000000 +1100 ++++ gtk+-2.4.1/gtk/gtkarrow.c 2004-05-26 14:52:17.000000000 +1000 +@@ -29,7 +29,7 @@ + #include "gtkarrow.h" + #include "gtkintl.h" + +-#define MIN_ARROW_SIZE 15 ++#define MIN_ARROW_SIZE 7 + + enum { + PROP_0, +@@ -53,6 +53,8 @@ + guint prop_id, + GValue *value, + GParamSpec *pspec); ++static void gtk_arrow_size_request (GtkWidget *arrow, ++ GtkRequisition *requisition); + + GType + gtk_arrow_get_type (void) +@@ -111,6 +113,7 @@ + G_PARAM_READABLE | G_PARAM_WRITABLE)); + + widget_class->expose_event = gtk_arrow_expose; ++ widget_class->size_request = gtk_arrow_size_request; + } + + static void +@@ -166,13 +169,18 @@ + } + + static void ++gtk_arrow_size_request (GtkWidget *arrow, ++ GtkRequisition *requisition) ++{ ++ requisition->width = MIN_ARROW_SIZE + GTK_MISC (arrow)->xpad * 2; ++ requisition->height = MIN_ARROW_SIZE + GTK_MISC (arrow)->ypad * 2; ++} ++ ++static void + gtk_arrow_init (GtkArrow *arrow) + { + GTK_WIDGET_SET_FLAGS (arrow, GTK_NO_WINDOW); + +- GTK_WIDGET (arrow)->requisition.width = MIN_ARROW_SIZE + GTK_MISC (arrow)->xpad * 2; +- GTK_WIDGET (arrow)->requisition.height = MIN_ARROW_SIZE + GTK_MISC (arrow)->ypad * 2; +- + arrow->arrow_type = GTK_ARROW_RIGHT; + arrow->shadow_type = GTK_SHADOW_OUT; + } +--- gtk+-2.4.1/gtk/gtkcalendar.c 2004-03-06 14:37:26.000000000 +1100 ++++ gtk+-2.4.1/gtk/gtkcalendar.c 2004-05-26 14:58:57.000000000 +1000 +@@ -340,6 +340,9 @@ + static void gtk_calendar_select_and_focus_day (GtkCalendar *calendar, + guint day); + ++static void gtk_calendar_do_select_day (GtkCalendar *calendar, ++ guint day); ++ + static void gtk_calendar_paint_arrow (GtkWidget *widget, + guint arrow); + static void gtk_calendar_paint_day_num (GtkWidget *widget, +@@ -861,13 +864,13 @@ + if (month_len < calendar->selected_day) + { + calendar->selected_day = 0; +- gtk_calendar_select_day (calendar, month_len); ++ gtk_calendar_do_select_day (calendar, month_len); + } + else + { + if (calendar->selected_day < 0) + calendar->selected_day = calendar->selected_day + 1 + month_length[leap (calendar->year)][calendar->month + 1]; +- gtk_calendar_select_day (calendar, calendar->selected_day); ++ gtk_calendar_do_select_day (calendar, calendar->selected_day); + } + + gtk_widget_queue_draw (GTK_WIDGET (calendar)); +@@ -908,10 +911,10 @@ + if (month_len < calendar->selected_day) + { + calendar->selected_day = 0; +- gtk_calendar_select_day (calendar, month_len); ++ gtk_calendar_do_select_day (calendar, month_len); + } + else +- gtk_calendar_select_day (calendar, calendar->selected_day); ++ gtk_calendar_do_select_day (calendar, calendar->selected_day); + + gtk_widget_queue_draw (GTK_WIDGET (calendar)); + gtk_calendar_thaw (calendar); +@@ -939,10 +942,10 @@ + if (month_len < calendar->selected_day) + { + calendar->selected_day = 0; +- gtk_calendar_select_day (calendar, month_len); ++ gtk_calendar_do_select_day (calendar, month_len); + } + else +- gtk_calendar_select_day (calendar, calendar->selected_day); ++ gtk_calendar_do_select_day (calendar, calendar->selected_day); + + gtk_widget_queue_draw (GTK_WIDGET (calendar)); + gtk_calendar_thaw (calendar); +@@ -974,10 +977,10 @@ + if (month_len < calendar->selected_day) + { + calendar->selected_day = 0; +- gtk_calendar_select_day (calendar, month_len); ++ gtk_calendar_do_select_day (calendar, month_len); + } + else +- gtk_calendar_select_day (calendar, calendar->selected_day); ++ gtk_calendar_do_select_day (calendar, calendar->selected_day); + + gtk_widget_queue_draw (GTK_WIDGET (calendar)); + gtk_calendar_thaw (calendar); +@@ -2480,9 +2483,9 @@ + return TRUE; + } + +-void +-gtk_calendar_select_day (GtkCalendar *calendar, +- guint day) ++static void ++gtk_calendar_do_select_day (GtkCalendar *calendar, ++ guint day) + { + g_return_if_fail (GTK_IS_CALENDAR (calendar)); + g_return_if_fail (day <= 31); +@@ -2499,6 +2502,13 @@ + if (GTK_WIDGET_DRAWABLE (GTK_WIDGET (calendar))) + gtk_calendar_paint_day_num (GTK_WIDGET (calendar), selected_day); + } ++} ++ ++void ++gtk_calendar_select_day (GtkCalendar *calendar, ++ guint day) ++{ ++ gtk_calendar_do_select_day (calendar, day); + + calendar->selected_day = day; + +--- gtk+-2.4.1/gtk/gtkentry.c 2004-04-22 08:08:08.000000000 +1000 ++++ gtk+-2.4.1/gtk/gtkentry.c 2004-05-26 14:52:17.000000000 +1000 +@@ -557,6 +557,15 @@ + 0.0, + G_PARAM_READABLE | G_PARAM_WRITABLE)); + ++ gtk_widget_class_install_style_property (widget_class, ++ g_param_spec_int ("min_width", ++ _("Minimum width"), ++ _("Minimum width of the entry field"), ++ 0, ++ G_MAXINT, ++ MIN_ENTRY_WIDTH, ++ G_PARAM_READABLE)); ++ + signals[POPULATE_POPUP] = + g_signal_new ("populate_popup", + G_OBJECT_CLASS_TYPE (gobject_class), +@@ -1124,7 +1133,7 @@ + { + GtkEntry *entry = GTK_ENTRY (widget); + PangoFontMetrics *metrics; +- gint xborder, yborder; ++ gint xborder, yborder, min_width; + PangoContext *context; + + gtk_widget_ensure_style (widget); +@@ -1140,9 +1149,11 @@ + + xborder += INNER_BORDER; + yborder += INNER_BORDER; +- ++ ++ gtk_widget_style_get (widget, "min_width", &min_width, NULL); ++ + if (entry->width_chars < 0) +- requisition->width = MIN_ENTRY_WIDTH + xborder * 2; ++ requisition->width = min_width + xborder * 2; + else + { + gint char_width = pango_font_metrics_get_approximate_char_width (metrics); +--- gtk+-2.4.1/gtk/gtkrange.c 2004-03-06 14:38:08.000000000 +1100 ++++ gtk+-2.4.1/gtk/gtkrange.c 2004-05-26 14:52:17.000000000 +1000 +@@ -180,6 +180,7 @@ + static GtkWidgetClass *parent_class = NULL; + static guint signals[LAST_SIGNAL]; + ++static GdkAtom recognize_protocols_atom, atom_atom; + + GType + gtk_range_get_type (void) +@@ -220,6 +221,9 @@ + object_class = (GtkObjectClass*) class; + widget_class = (GtkWidgetClass*) class; + ++ recognize_protocols_atom = gdk_atom_intern ("RECOGNIZE_PROTOCOLS", FALSE); ++ atom_atom = gdk_atom_intern ("ATOM", FALSE); ++ + parent_class = g_type_class_peek_parent (class); + + gobject_class->set_property = gtk_range_set_property; +@@ -815,6 +819,12 @@ + &attributes, attributes_mask); + gdk_window_set_user_data (range->event_window, range); + ++ gdk_property_change (range->event_window, ++ recognize_protocols_atom, ++ atom_atom, ++ 32, GDK_PROP_MODE_REPLACE, ++ NULL, 0); ++ + widget->style = gtk_style_attach (widget->style, widget->window); + } + +@@ -1186,7 +1196,7 @@ + + /* ignore presses when we're already doing something else. */ + if (range->layout->grab_location != MOUSE_OUTSIDE) +- return FALSE; ++ return TRUE; + + range->layout->mouse_x = event->x; + range->layout->mouse_y = event->y; +@@ -1364,7 +1374,7 @@ + return TRUE; + } + +- return FALSE; ++ return TRUE; + } + + /** diff --git a/packages/gtk+/gtk+-2.10.6/gtklabel-resize-patch b/packages/gtk+/gtk+-2.10.6/gtklabel-resize-patch new file mode 100644 index 0000000000..df29656343 --- /dev/null +++ b/packages/gtk+/gtk+-2.10.6/gtklabel-resize-patch @@ -0,0 +1,10 @@ +--- gtk+-2.4.3/gtk/gtklabel.c~ 2004-06-11 13:50:34.000000000 +0100 ++++ gtk+-2.4.3/gtk/gtklabel.c 2004-07-05 13:33:57.000000000 +0100 +@@ -1623,6 +1623,7 @@ + + /* We have to clear the layout, fonts etc. may have changed */ + gtk_label_clear_layout (label); ++ gtk_widget_queue_resize (GTK_WIDGET (label)); + } + + static void diff --git a/packages/gtk+/gtk+-2.10.6/hardcoded_libtool.patch b/packages/gtk+/gtk+-2.10.6/hardcoded_libtool.patch new file mode 100644 index 0000000000..bdbdb32f97 --- /dev/null +++ b/packages/gtk+/gtk+-2.10.6/hardcoded_libtool.patch @@ -0,0 +1,29 @@ +--- gtk+-2.10.0/configure.in.orig 2006-07-07 09:31:34.000000000 +0100 ++++ gtk+-2.10.0/configure.in 2006-07-07 09:32:49.000000000 +0100 +@@ -370,7 +370,7 @@ + AC_MSG_CHECKING([Whether to write dependencies into .pc files]) + case $enable_explicit_deps in + auto) +- deplibs_check_method=`(./libtool --config; echo eval echo \\$deplibs_check_method) | sh` ++ deplibs_check_method=`(./$host_alias-libtool --config; echo eval echo \\$deplibs_check_method) | sh` + if test "x$deplibs_check_method" '!=' xpass_all || test "x$enable_static" = xyes ; then + enable_explicit_deps=yes + else +@@ -768,7 +768,7 @@ + dnl Now we check to see if our libtool supports shared lib deps + dnl (in a rather ugly way even) + if $dynworks; then +- pixbuf_libtool_config="${CONFIG_SHELL-/bin/sh} ./libtool --config" ++ pixbuf_libtool_config="${CONFIG_SHELL-/bin/sh} ./$host_alias-libtool --config" + pixbuf_deplibs_check=`$pixbuf_libtool_config | \ + grep '^[[a-z_]]*check[[a-z_]]*_method=[['\''"]]' | \ + sed 's/.*[['\''"]]\(.*\)[['\''"]]$/\1/'` +@@ -1600,7 +1600,7 @@ + # + # We are using gmodule-no-export now, but I'm leaving the stripping + # code in place for now, since pango and atk still require gmodule. +-export_dynamic=`(./libtool --config; echo eval echo \\$export_dynamic_flag_spec) | sh` ++export_dynamic=`(./$host_alias-libtool --config; echo eval echo \\$export_dynamic_flag_spec) | sh` + if test -n "$export_dynamic"; then + GDK_PIXBUF_DEP_LIBS=`echo $GDK_PIXBUF_DEP_LIBS | sed -e "s/$export_dynamic//"` + GDK_PIXBUF_XLIB_DEP_LIBS=`echo $GDK_PIXBUF_XLIB_DEP_LIBS | sed -e "s/$export_dynamic//"` diff --git a/packages/gtk+/gtk+-2.10.6/menu-deactivate.patch b/packages/gtk+/gtk+-2.10.6/menu-deactivate.patch new file mode 100644 index 0000000000..cfb8849e9f --- /dev/null +++ b/packages/gtk+/gtk+-2.10.6/menu-deactivate.patch @@ -0,0 +1,51 @@ +--- gtk+-2.10.0/gtk/gtkmenushell.c.orig 2006-07-05 17:17:34.000000000 +0200 ++++ gtk+-2.10.0/gtk/gtkmenushell.c 2006-07-05 17:19:01.000000000 +0200 +@@ -42,7 +42,7 @@ + #include "gtkintl.h" + #include "gtkalias.h" + +-#define MENU_SHELL_TIMEOUT 500 ++#define MENU_SHELL_TIMEOUT 2000 + + #define PACK_DIRECTION(m) \ + (GTK_IS_MENU_BAR (m) \ +@@ -203,6 +203,8 @@ + + G_DEFINE_TYPE (GtkMenuShell, gtk_menu_shell, GTK_TYPE_CONTAINER) + ++static int last_crossing_time; ++ + static void + gtk_menu_shell_class_init (GtkMenuShellClass *klass) + { +@@ -517,6 +519,7 @@ + gtk_grab_add (GTK_WIDGET (menu_shell)); + menu_shell->have_grab = TRUE; + menu_shell->active = TRUE; ++ last_crossing_time = 0; + } + } + +@@ -669,6 +672,13 @@ + menu_shell->activate_time = 0; + deactivate = FALSE; + } ++ ++ if (last_crossing_time != 0 ++ && ((event->time - last_crossing_time) < 500)) ++ { ++ last_crossing_time = 0; ++ deactivate = FALSE; ++ } + + if (deactivate) + { +@@ -716,6 +726,8 @@ + { + menu_item = gtk_get_event_widget ((GdkEvent*) event); + ++ last_crossing_time = event->time; ++ + if (!menu_item || + (GTK_IS_MENU_ITEM (menu_item) && + !_gtk_menu_item_is_selectable (menu_item))) diff --git a/packages/gtk+/gtk+-2.10.6/migration.patch b/packages/gtk+/gtk+-2.10.6/migration.patch new file mode 100644 index 0000000000..4ee786e688 --- /dev/null +++ b/packages/gtk+/gtk+-2.10.6/migration.patch @@ -0,0 +1,611 @@ +Index: configure.in +=================================================================== +--- configure.in.orig 2006-10-03 17:54:09.000000000 +0100 ++++ configure.in 2006-10-30 12:58:33.000000000 +0000 +@@ -1529,6 +1529,16 @@ + GTK_EXTRA_CFLAGS="$msnative_struct" + fi + ++AC_ARG_ENABLE(display-migration, ++ [AC_HELP_STRING([--enable-display-migration], ++ [include support for GPE_CHANGE_DISPLAY protocol])], ++ enable_migration=yes, enable_migration=no) ++if test "$enable_migration" = "yes"; then ++ AC_DEFINE([ENABLE_MIGRATION], 1, [Define if display migration is enabled]) ++ GTK_DEP_LIBS="$GTK_DEP_LIBS -lgcrypt" ++fi ++AM_CONDITIONAL(ENABLE_MIGRATION, test $enable_migration = "yes") ++ + AC_SUBST(GTK_PACKAGES) + AC_SUBST(GTK_EXTRA_LIBS) + AC_SUBST(GTK_EXTRA_CFLAGS) +Index: gtk/Makefile.am +=================================================================== +--- gtk/Makefile.am.orig 2006-10-02 18:27:53.000000000 +0100 ++++ gtk/Makefile.am 2006-10-30 12:59:14.000000000 +0000 +@@ -589,6 +589,11 @@ + gtkwindow-decorate.c \ + gtkwindow.c \ + $(gtk_clipboard_dnd_c_sources) ++ ++if ENABLE_MIGRATION ++gtk_base_c_sources += gtkmigration.c ++endif ++ + gtk_c_sources = $(gtk_base_c_sources) + gtk_all_c_sources = $(gtk_base_c_sources) + +Index: gtk/gtkmain.c +=================================================================== +--- gtk/gtkmain.c.orig 2006-09-03 06:31:21.000000000 +0100 ++++ gtk/gtkmain.c 2006-10-30 12:56:34.000000000 +0000 +@@ -507,6 +507,10 @@ + _gtk_accel_map_init (); + _gtk_rc_init (); + ++#ifdef ENABLE_MIGRATION ++ gtk_migration_init (); ++#endif ++ + /* Set the 'initialized' flag. + */ + gtk_initialized = TRUE; +Index: gtk/gtkmigration.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ gtk/gtkmigration.c 2006-10-30 12:56:34.000000000 +0000 +@@ -0,0 +1,529 @@ ++/* ++ * Copyright (C) 2003, 2005 Philip Blundell <philb@gnu.org> ++ * ++ * 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. ++ */ ++ ++#include <stdlib.h> ++#include <ctype.h> ++#include <libintl.h> ++#include <string.h> ++#include <assert.h> ++ ++#include <X11/X.h> ++#include <X11/Xlib.h> ++#include <X11/Xatom.h> ++ ++#include <gcrypt.h> ++ ++#include "gtk.h" ++#include "gdk.h" ++#include "x11/gdkx.h" ++ ++#define _(x) gettext(x) ++ ++static GdkAtom string_gdkatom, display_change_gdkatom; ++static GdkAtom rsa_challenge_gdkatom; ++ ++#define DISPLAY_CHANGE_SUCCESS 0 ++#define DISPLAY_CHANGE_UNABLE_TO_CONNECT 1 ++#define DISPLAY_CHANGE_NO_SUCH_SCREEN 2 ++#define DISPLAY_CHANGE_AUTHENTICATION_BAD 3 ++#define DISPLAY_CHANGE_INDETERMINATE_ERROR 4 ++ ++static gboolean no_auth; ++ ++static GSList *all_widgets; ++ ++static gboolean gtk_migration_initialised; ++ ++#define CHALLENGE_LEN 64 ++ ++gchar *gtk_migration_auth_challenge_string; ++ ++static unsigned char challenge_bytes[CHALLENGE_LEN]; ++static unsigned long challenge_seq; ++ ++#define hexbyte(x) ((x) >= 10 ? (x) + 'a' - 10 : (x) + '0') ++ ++struct rsa_key ++{ ++ gcry_mpi_t n, e, d, p, q, u; ++}; ++ ++static gcry_mpi_t ++mpi_from_sexp (gcry_sexp_t r, char *tag) ++{ ++ gcry_sexp_t s = gcry_sexp_find_token (r, tag, 0); ++ return gcry_sexp_nth_mpi (s, 1, GCRYMPI_FMT_USG); ++} ++ ++static char * ++hex_from_mpi (gcry_mpi_t m) ++{ ++ char *buf; ++ gcry_mpi_aprint (GCRYMPI_FMT_HEX, (void *)&buf, NULL, m); ++ return buf; ++} ++ ++static void ++gtk_migration_crypt_create_hash (char *display, char *challenge, size_t len, char *result) ++{ ++ size_t dlen = strlen (display); ++ gchar *buf = g_malloc (dlen + 1 + len); ++ strcpy (buf, display); ++ memcpy (buf + dlen + 1, challenge, len); ++ gcry_md_hash_buffer (GCRY_MD_SHA1, result, buf, len + dlen + 1); ++ g_free (buf); ++} ++ ++static int ++do_encode_md (const unsigned char *digest, size_t digestlen, int algo, ++ unsigned int nbits, gcry_mpi_t *r_val) ++{ ++ int nframe = (nbits+7) / 8; ++ unsigned char *frame; ++ int i, n; ++ unsigned char asn[100]; ++ size_t asnlen; ++ ++ asnlen = sizeof(asn); ++ if (gcry_md_algo_info (algo, GCRYCTL_GET_ASNOID, asn, &asnlen)) ++ return -1; ++ ++ if (digestlen + asnlen + 4 > nframe ) ++ return -1; ++ ++ /* We encode the MD in this way: ++ * ++ * 0 1 PAD(n bytes) 0 ASN(asnlen bytes) MD(len bytes) ++ * ++ * PAD consists of FF bytes. ++ */ ++ frame = g_malloc (nframe); ++ n = 0; ++ frame[n++] = 0; ++ frame[n++] = 1; /* block type */ ++ i = nframe - digestlen - asnlen -3 ; ++ assert ( i > 1 ); ++ memset ( frame+n, 0xff, i ); n += i; ++ frame[n++] = 0; ++ memcpy ( frame+n, asn, asnlen ); n += asnlen; ++ memcpy ( frame+n, digest, digestlen ); n += digestlen; ++ assert ( n == nframe ); ++ ++ gcry_mpi_scan (r_val, GCRYMPI_FMT_USG, frame, nframe, &nframe); ++ g_free (frame); ++ return 0; ++} ++ ++static gboolean ++gtk_migration_crypt_check_signature (struct rsa_key *k, char *hash, char *sigbuf) ++{ ++ gcry_mpi_t mpi, mpi2; ++ gcry_sexp_t data, sig, key; ++ int rc; ++ ++ do_encode_md (hash, 20, GCRY_MD_SHA1, 1024, &mpi); ++ ++ gcry_sexp_build (&data, NULL, "(data (value %m))", mpi); ++ ++ gcry_mpi_release (mpi); ++ ++ gcry_sexp_build (&key, NULL, "(public-key (rsa (n %m) (e %m)))", k->n, k->e); ++ ++ if (gcry_mpi_scan (&mpi2, GCRYMPI_FMT_HEX, sigbuf, 0, NULL)) ++ { ++ gcry_sexp_release (data); ++ return FALSE; ++ } ++ ++ gcry_sexp_build (&sig, NULL, "(sig-val (rsa (s %m)))", mpi2); ++ ++ rc = gcry_pk_verify (sig, data, key); ++ ++ gcry_sexp_release (data); ++ gcry_sexp_release (key); ++ gcry_sexp_release (sig); ++ gcry_mpi_release (mpi2); ++ ++ if (rc) ++ return FALSE; ++ ++ return TRUE; ++} ++ ++static void ++gtk_migration_auth_update_challenge (void) ++{ ++ int i; ++ unsigned char *p; ++ ++ if (gtk_migration_auth_challenge_string == NULL) ++ gtk_migration_auth_challenge_string = g_malloc ((CHALLENGE_LEN * 2) + 9); ++ ++ p = gtk_migration_auth_challenge_string; ++ ++ for (i = 0; i < CHALLENGE_LEN; i++) ++ { ++ *p++ = hexbyte (challenge_bytes[i] >> 4); ++ *p++ = hexbyte (challenge_bytes[i] & 15); ++ } ++ ++ sprintf (p, "%08lx", challenge_seq++); ++} ++ ++static void ++gtk_migration_auth_generate_challenge (void) ++{ ++ gcry_randomize (challenge_bytes, sizeof (challenge_bytes), GCRY_STRONG_RANDOM); ++ gtk_migration_auth_update_challenge (); ++} ++ ++static struct rsa_key * ++parse_pubkey (char *s) ++{ ++ struct rsa_key *r; ++ gcry_mpi_t n, e; ++ gchar *sp; ++ ++ sp = strtok (s, " \n"); ++ gcry_mpi_scan (&e, GCRYMPI_FMT_HEX, sp, 0, NULL); ++ sp = strtok (NULL, " \n"); ++ gcry_mpi_scan (&n, GCRYMPI_FMT_HEX, sp, 0, NULL); ++ ++ r = g_malloc0 (sizeof (struct rsa_key)); ++ r->e = e; ++ r->n = n; ++ return r; ++} ++ ++static struct rsa_key * ++lookup_pubkey (u_int32_t id) ++{ ++ const gchar *home_dir = g_get_home_dir (); ++ gchar *filename = g_strdup_printf ("%s/.gpe/migrate/public", home_dir); ++ FILE *fp = fopen (filename, "r"); ++ struct rsa_key *r = NULL; ++ ++ if (fp) ++ { ++ while (!feof (fp)) ++ { ++ char buffer[4096]; ++ if (fgets (buffer, 4096, fp)) ++ { ++ char *p; ++ u_int32_t this_id = strtoul (buffer, &p, 16); ++ if (p != buffer && *p == ' ') ++ { ++#ifdef DEBUG ++ fprintf (stderr, "found id %x\n", this_id); ++#endif ++ if (this_id == id) ++ { ++ r = parse_pubkey (++p); ++ break; ++ } ++ } ++ } ++ } ++ fclose (fp); ++ } ++ ++ g_free (filename); ++ return r; ++} ++ ++static void ++free_pubkey (struct rsa_key *k) ++{ ++ gcry_mpi_release (k->n); ++ gcry_mpi_release (k->e); ++ ++ g_free (k); ++} ++ ++static gboolean ++gtk_migration_auth_validate_request (char *display, char *data) ++{ ++ u_int32_t key_id; ++ char *ep; ++ char *p; ++ struct rsa_key *k; ++ char hash[20]; ++ gboolean rc; ++ ++ p = strchr (data, ' '); ++ if (p == NULL) ++ return FALSE; ++ *p++ = 0; ++ ++ key_id = strtoul (data, &ep, 16); ++ if (*ep) ++ return FALSE; ++ ++ k = lookup_pubkey (key_id); ++ if (k == NULL) ++ return FALSE; ++ ++ gtk_migration_crypt_create_hash (display, gtk_migration_auth_challenge_string, ++ strlen (gtk_migration_auth_challenge_string), hash); ++ ++ rc = gtk_migration_crypt_check_signature (k, hash, p); ++ ++ free_pubkey (k); ++ ++ return rc; ++} ++ ++static int ++do_change_display (GtkWidget *w, char *display_name) ++{ ++ GdkDisplay *newdisplay; ++ guint screen_nr = 1; ++ guint i; ++ ++ if (display_name[0] == 0) ++ return DISPLAY_CHANGE_INDETERMINATE_ERROR; ++ ++ i = strlen (display_name) - 1; ++ while (i > 0 && isdigit (display_name[i])) ++ i--; ++ ++ if (display_name[i] == '.') ++ { ++ screen_nr = atoi (display_name + i + 1); ++ display_name[i] = 0; ++ } ++ ++ newdisplay = gdk_display_open (display_name); ++ if (newdisplay) ++ { ++ GdkScreen *screen = gdk_display_get_screen (newdisplay, screen_nr); ++ if (screen) ++ { ++ gtk_window_set_screen (GTK_WINDOW (w), screen); ++ gdk_display_manager_set_default_display (gdk_display_manager_get (), ++ newdisplay); ++ return DISPLAY_CHANGE_SUCCESS; ++ } ++ else ++ return DISPLAY_CHANGE_NO_SUCH_SCREEN; ++ } ++ ++ return DISPLAY_CHANGE_UNABLE_TO_CONNECT; ++} ++ ++static void ++set_challenge_on_window (GdkWindow *window) ++{ ++ gdk_property_change (window, rsa_challenge_gdkatom, string_gdkatom, ++ 8, GDK_PROP_MODE_REPLACE, gtk_migration_auth_challenge_string, ++ strlen (gtk_migration_auth_challenge_string)); ++} ++ ++static void ++update_challenge_on_windows (void) ++{ ++ GSList *i; ++ ++ gtk_migration_auth_update_challenge (); ++ ++ for (i = all_widgets; i; i = i->next) ++ { ++ GtkWidget *w = GTK_WIDGET (i->data); ++ if (w->window) ++ set_challenge_on_window (w->window); ++ } ++} ++ ++static void ++reset_state (GdkWindow *window) ++{ ++ gdk_property_change (window, display_change_gdkatom, string_gdkatom, ++ 8, GDK_PROP_MODE_REPLACE, NULL, 0); ++} ++ ++static void ++generate_response (GdkDisplay *gdisplay, Display *dpy, Window window, int code) ++{ ++ XClientMessageEvent ev; ++ Atom atom = gdk_x11_atom_to_xatom_for_display (gdisplay, ++ display_change_gdkatom); ++ ++ memset (&ev, 0, sizeof (ev)); ++ ++ ev.type = ClientMessage; ++ ev.window = window; ++ ev.message_type = atom; ++ ev.format = 32; ++ ++ ev.data.l[0] = window; ++ ev.data.l[1] = code; ++ ++ XSendEvent (dpy, DefaultRootWindow (dpy), False, SubstructureNotifyMask, (XEvent *)&ev); ++} ++ ++static int ++handle_request (GdkWindow *gwindow, char *prop) ++{ ++ GtkWidget *widget; ++ char *target, *auth_method, *auth_data; ++ char *p; ++ ++ target = prop; ++ auth_method = "NULL"; ++ auth_data = NULL; ++ ++ p = strchr (prop, ' '); ++ if (p) ++ { ++ *p = 0; ++ auth_method = ++p; ++ ++ p = strchr (p, ' '); ++ if (p) ++ { ++ *p = 0; ++ auth_data = ++p; ++ } ++ } ++ ++ if (no_auth == FALSE) ++ { ++ if (!strcasecmp (auth_method, "null")) ++ return DISPLAY_CHANGE_AUTHENTICATION_BAD; ++ else if (!strcasecmp (auth_method, "rsa-sig")) ++ { ++ if (gtk_migration_auth_validate_request (target, auth_data) == FALSE) ++ return DISPLAY_CHANGE_AUTHENTICATION_BAD; ++ } ++ else ++ return DISPLAY_CHANGE_AUTHENTICATION_BAD; ++ } ++ ++ gdk_window_get_user_data (gwindow, (gpointer*) &widget); ++ ++ if (widget) ++ return do_change_display (widget, target); ++ ++ return DISPLAY_CHANGE_INDETERMINATE_ERROR; ++} ++ ++static GdkFilterReturn ++filter_func (GdkXEvent *xevp, GdkEvent *ev, gpointer p) ++{ ++ XPropertyEvent *xev = (XPropertyEvent *)xevp; ++ ++ if (xev->type == PropertyNotify) ++ { ++ GdkDisplay *gdisplay; ++ Atom atom; ++ ++ gdisplay = gdk_x11_lookup_xdisplay (xev->display); ++ if (gdisplay) ++ { ++ atom = gdk_x11_atom_to_xatom_for_display (gdisplay, display_change_gdkatom); ++ ++ if (xev->atom == atom) ++ { ++ GdkWindow *gwindow; ++ ++ gwindow = gdk_window_lookup_for_display (gdisplay, xev->window); ++ ++ if (gwindow) ++ { ++ GdkAtom actual_type; ++ gint actual_format; ++ gint actual_length; ++ unsigned char *prop = NULL; ++ ++ if (gdk_property_get (gwindow, display_change_gdkatom, string_gdkatom, ++ 0, G_MAXLONG, FALSE, |
