--- gtkbutton.c	Mon Feb 12 21:36:37 2001
+++ gtk+-1.2.10-with-validation/gtk/gtkbutton.c	Wed Dec 19 01:35:49 2001
@@ -333,7 +333,10 @@
   g_return_if_fail (button != NULL);
   g_return_if_fail (GTK_IS_BUTTON (button));
 
-  gtk_signal_emit (GTK_OBJECT (button), button_signals[CLICKED]);
+#ifdef VALIDATE
+  if( !GTK_WIDGET_IGNOREACTIVATE(GTK_WIDGET(button)) )
+#endif
+    gtk_signal_emit (GTK_OBJECT (button), button_signals[CLICKED]);
 }
 
 void

--- gtkcombo.c	Thu Mar 15 19:41:40 2001
+++ gtk+-1.2.10-with-validation/gtk/gtkcombo.c	Tue Dec 18 12:03:44 2001
@@ -480,6 +480,10 @@
 gtk_combo_update_entry (GtkList * list, GtkCombo * combo)
 {
   char *text;
+#ifdef VALIDATE
+  if( GTK_WIDGET_IGNOREACTIVATE(GTK_WIDGET(combo->entry)) )
+    return;
+#endif
 
   gtk_grab_remove (GTK_WIDGET (combo));
   gtk_signal_handler_block (GTK_OBJECT (list), combo->list_change_id);

--- gtkwidget.c	Thu Mar  1 10:35:50 2001
+++ gtk+-1.2.10-with-validation/gtk/gtkwidget.c	Tue Jan  1 16:06:53 2002
@@ -97,6 +97,9 @@
   NO_EXPOSE_EVENT,
   VISIBILITY_NOTIFY_EVENT,
   DEBUG_MSG,
+#ifdef VALIDATE
+  VALIDATE_EVENT,
+#endif
   LAST_SIGNAL
 };
 
@@ -506,6 +509,18 @@
 		    gtk_marshal_BOOL__POINTER,
 		    GTK_TYPE_BOOL, 1,
 		    GTK_TYPE_GDK_EVENT);
+
+#ifdef VALIDATE
+  widget_signals[VALIDATE_EVENT] =
+    gtk_signal_new ("validate_event",
+		    GTK_RUN_LAST,
+		    object_class->type,
+		    GTK_SIGNAL_OFFSET (GtkWidgetClass, validate_event),
+		    gtk_marshal_BOOL__POINTER,
+		    GTK_TYPE_BOOL, 1,
+		    GTK_TYPE_GDK_EVENT);
+#endif
+
   widget_signals[FOCUS_IN_EVENT] =
     gtk_signal_new ("focus_in_event",
 		    GTK_RUN_LAST,
@@ -760,6 +775,9 @@
   klass->enter_notify_event = NULL;
   klass->leave_notify_event = NULL;
   klass->configure_event = NULL;
+#ifdef VALIDATE
+  klass->validate_event = NULL;
+#endif
   klass->focus_in_event = NULL;
   klass->focus_out_event = NULL;
   klass->map_event = NULL;
@@ -1017,10 +1035,18 @@
   widget->window = NULL;
   widget->parent = NULL;
 
+#ifdef VALIDATE
+  GTK_WIDGET_SET_FLAGS (widget,
+			GTK_SENSITIVE |
+			GTK_PARENT_SENSITIVE |
+			GTK_CAUSESVALIDATION |
+			(composite_child_stack ? GTK_COMPOSITE_CHILD : 0));
+#else
   GTK_WIDGET_SET_FLAGS (widget,
 			GTK_SENSITIVE |
 			GTK_PARENT_SENSITIVE |
 			(composite_child_stack ? GTK_COMPOSITE_CHILD : 0));
+#endif
 
   widget->style = gtk_widget_peek_style ();
   gtk_style_ref (widget->style);
@@ -3119,11 +3145,41 @@
 	       * toplevel window can request the focus if necessary.
 	       * This is needed when the toplevel is a GtkPlug
 	       */
+#ifdef VALIDATE
+    	      GTK_WIDGET_UNSET_FLAGS(focus_widget, GTK_IGNOREACTIVATE); 
+#endif
 	      if (!GTK_WIDGET_HAS_FOCUS (widget))
 		gtk_window_set_focus (GTK_WINDOW (toplevel), focus_widget);
 
 	      return;
 	    }
+#ifdef VALIDATE
+	  /* Check if the widget that get the focus causes validation */ 
+	  if( GTK_WIDGET_CAUSESVALIDATION(focus_widget) ) {
+	    /* Check if the there exists a previously focused widget  */ 
+	    if( widget ) {
+	      /* Start of the validation process */ 
+	      /* Initialize the return value of the validate event to TRUE, 
+		 Just in case there is no validate event handler for this widget */
+	      int validate_return_val = TRUE, foo=4321;
+	      /* I don't really know what is the fourth parameter for */ 
+	      gtk_signal_emit (GTK_OBJECT (widget), widget_signals[VALIDATE_EVENT], 
+			       &validate_return_val, &foo); 
+	      /* Look at the return value of the validation */ 
+	      if( validate_return_val == FALSE ) {
+		/* Ignore the activate event of the focus that 
+		   wanted to get the focus, as it must not get the focus */ 
+		GTK_WIDGET_SET_FLAGS(focus_widget, GTK_IGNOREACTIVATE);
+		/* don't set the focus to the required widget, but to the old one */
+		focus_widget = widget;
+	      } else { /* The widget is valid */ 
+		/* Unset the IGNOREACTIVATE flag, as now the widget 
+		   is allowed to get the focus */
+		GTK_WIDGET_UNSET_FLAGS(focus_widget, GTK_IGNOREACTIVATE); 
+	      }
+	    }
+	  }
+#endif
 	  
 	  if (widget)
 	    {

--- gtkwidget.h	Thu Nov 30 02:59:10 2000
+++ gtk+-1.2.10-with-validation/gtk/gtkwidget.h	Wed Dec 19 01:11:15 2001
@@ -34,6 +34,8 @@
 #include <gtk/gtkstyle.h>
 
 
+#define VALIDATE 1
+
 #ifdef __cplusplus
 extern "C" {
 #endif /* __cplusplus */
@@ -71,6 +73,10 @@
   /* the widget when focused will receive the default action and have
    * HAS_DEFAULT set even if there is a different widget set as default */
   GTK_RECEIVES_DEFAULT = 1 << 20
+#ifdef VALIDATE
+  , GTK_IGNOREACTIVATE = 1 << 21
+  , GTK_CAUSESVALIDATION = 1 << 22
+#endif
 } GtkWidgetFlags;
 
 /* Macro for casting a pointer to a GtkWidget or GtkWidgetClass pointer.
@@ -110,6 +116,11 @@
 #define GTK_WIDGET_COMPOSITE_CHILD(wid)	  ((GTK_WIDGET_FLAGS (wid) & GTK_COMPOSITE_CHILD) != 0)
 #define GTK_WIDGET_APP_PAINTABLE(wid)	  ((GTK_WIDGET_FLAGS (wid) & GTK_APP_PAINTABLE) != 0)
 #define GTK_WIDGET_RECEIVES_DEFAULT(wid)  ((GTK_WIDGET_FLAGS (wid) & GTK_RECEIVES_DEFAULT) != 0)
+
+#ifdef VALIDATE
+#define GTK_WIDGET_CAUSESVALIDATION(wid)  ((GTK_WIDGET_FLAGS (wid) & GTK_CAUSESVALIDATION) != 0)
+#define GTK_WIDGET_IGNOREACTIVATE(wid)  ((GTK_WIDGET_FLAGS (wid) & GTK_IGNOREACTIVATE) != 0)
+#endif
   
 /* Macros for setting and clearing widget flags.
  */
@@ -324,6 +335,10 @@
 				    GdkEventCrossing   *event);
   gint (* configure_event)	   (GtkWidget	       *widget,
 				    GdkEventConfigure  *event);
+#ifdef VALIDATE
+  gint (* validate_event)	   (GtkWidget	       *widget,
+				    GdkEventFocus      *event);
+#endif
   gint (* focus_in_event)	   (GtkWidget	       *widget,
 				    GdkEventFocus      *event);
   gint (* focus_out_event)	   (GtkWidget	       *widget,

--- testgtk.c	Mon Feb 26 21:18:44 2001
+++ gtk+-1.2.10-with-validation/gtk/testgtk.c	Wed Dec 19 00:43:48 2001
@@ -2776,6 +2776,40 @@
 			 GTK_TOGGLE_BUTTON(checkbutton)->active);
 }
 
+#ifdef VALIDATE
+
+static void
+on_entry_validate_event (GtkEntry *entry,
+			 gint *result,
+			 gpointer data)
+{
+  g_print("on_entry_validate_event: result=%d, data=%p\n", *result, data);
+  if( *gtk_entry_get_text(entry) != 'a') {
+    create_dialog();
+    *result = FALSE;
+  }
+}
+
+static void
+on_editable_check_validate_event (GtkWidget *checkbutton,
+				  gint *result,
+				  gpointer user_data)
+{
+  g_warning("on_editable_check_validate_event\n");
+  *result = 1;
+}
+
+static void
+on_cb_validate_event (GtkWidget *checkbutton,
+		      gint *result,
+		      gpointer user_data)
+{
+  g_warning("on_cb_validate_event\n");
+  *result = 1;
+}
+
+#endif
+
 static void
 create_entry (void)
 {
@@ -2876,6 +2910,19 @@
       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
       gtk_widget_grab_default (button);
       gtk_widget_show (button);
+
+#ifdef VALIDATE
+  gtk_signal_connect (GTK_OBJECT (entry), "validate_event",
+                      GTK_SIGNAL_FUNC (on_entry_validate_event),
+                      (gpointer)0x1234);
+  gtk_signal_connect (GTK_OBJECT (cb), "validate_event",
+                      GTK_SIGNAL_FUNC (on_cb_validate_event),
+                      NULL);
+  gtk_signal_connect (GTK_OBJECT (editable_check), "validate_event",
+                      GTK_SIGNAL_FUNC (on_editable_check_validate_event),
+                      NULL);
+#endif
+
     }
 
   if (!GTK_WIDGET_VISIBLE (window))





