X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtkmain.c;h=62f337fa6e3562411b3b384025c0ce469ea2e812;hb=0101a46dcd297437d46b59ababdb79ecda4bfe9c;hp=3e1cd8c43e9ac9d5b91faa2749d623fbf62c7bd1;hpb=62dba86c81debf2677230c674902ddb98ba8e4c2;p=~andy%2Fgtk diff --git a/gtk/gtkmain.c b/gtk/gtkmain.c index 3e1cd8c43..62f337fa6 100644 --- a/gtk/gtkmain.c +++ b/gtk/gtkmain.c @@ -12,17 +12,24 @@ * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. */ +#include /* so we get the right setlocale */ #include #include +#include +#include #include "gtkbutton.h" +#include "gtkdnd.h" +#include "gtkfeatures.h" #include "gtkhscrollbar.h" #include "gtkhseparator.h" #include "gtkmain.h" #include "gtkpreview.h" #include "gtkrc.h" +#include "gtkscrolledwindow.h" #include "gtkselection.h" #include "gtksignal.h" #include "gtktable.h" @@ -32,15 +39,17 @@ #include "gtkwidget.h" #include "gtkwindow.h" #include "gtkprivate.h" - +#include "gdk/gdki18n.h" +#include "config.h" +#include "gtkdebug.h" +#include "gtkintl.h" /* Private type definitions */ -typedef struct _GtkInitFunction GtkInitFunction; -typedef struct _GtkTimeoutFunction GtkTimeoutFunction; -typedef struct _GtkIdleFunction GtkIdleFunction; -typedef struct _GtkInputFunction GtkInputFunction; -typedef struct _GtkKeySnooperData GtkKeySnooperData; +typedef struct _GtkInitFunction GtkInitFunction; +typedef struct _GtkQuitFunction GtkQuitFunction; +typedef struct _GtkClosure GtkClosure; +typedef struct _GtkKeySnooperData GtkKeySnooperData; struct _GtkInitFunction { @@ -48,31 +57,19 @@ struct _GtkInitFunction gpointer data; }; -struct _GtkTimeoutFunction -{ - gint tag; - guint32 start; - guint32 interval; - guint32 originterval; - GtkFunction function; - GtkCallbackMarshal marshal; - gpointer data; - GtkDestroyNotify destroy; -}; - -struct _GtkIdleFunction +struct _GtkQuitFunction { - gint tag; - gint priority; + guint id; + guint main_level; GtkCallbackMarshal marshal; GtkFunction function; gpointer data; GtkDestroyNotify destroy; }; -struct _GtkInputFunction +struct _GtkClosure { - GtkCallbackMarshal callback; + GtkCallbackMarshal marshal; gpointer data; GtkDestroyNotify destroy; }; @@ -81,56 +78,48 @@ struct _GtkKeySnooperData { GtkKeySnoopFunc func; gpointer func_data; - gint id; + guint id; }; static void gtk_exit_func (void); -static void gtk_timeout_insert (GtkTimeoutFunction *timeoutf); -static void gtk_handle_current_timeouts (guint32 the_time); -static void gtk_handle_current_idles (void); -static gint gtk_invoke_key_snoopers (GtkWidget *grab_widget, - GdkEvent *event); -static void gtk_handle_timeouts (void); -static void gtk_handle_idle (void); -static void gtk_handle_timer (void); -static void gtk_propagate_event (GtkWidget *widget, +static gint gtk_quit_invoke_function (GtkQuitFunction *quitf); +static void gtk_quit_destroy (GtkQuitFunction *quitf); +static gint gtk_invoke_key_snoopers (GtkWidget *grab_widget, GdkEvent *event); + +static void gtk_destroy_closure (gpointer data); +static gboolean gtk_invoke_idle_timeout (gpointer data); +static void gtk_invoke_input (gpointer data, + gint source, + GdkInputCondition condition); + +#if 0 static void gtk_error (gchar *str); static void gtk_warning (gchar *str); static void gtk_message (gchar *str); static void gtk_print (gchar *str); +#endif -static gint gtk_idle_compare (gpointer a, - gpointer b); - -static gint gtk_timeout_compare (gpointer a, - gpointer b); +const guint gtk_major_version = GTK_MAJOR_VERSION; +const guint gtk_minor_version = GTK_MINOR_VERSION; +const guint gtk_micro_version = GTK_MICRO_VERSION; +const guint gtk_binary_age = GTK_BINARY_AGE; +const guint gtk_interface_age = GTK_INTERFACE_AGE; -static gboolean iteration_done = FALSE; -static guint main_level = 0; -static gint initialized = FALSE; -static GdkEvent *next_event = NULL; +static guint gtk_main_loop_level = 0; +static gint gtk_initialized = FALSE; static GList *current_events = NULL; +static GSList *main_loops = NULL; /* stack of currently executing main loops */ + static GSList *grabs = NULL; /* A stack of unique grabs. The grabbing * widget is the first one on the list. */ static GList *init_functions = NULL; /* A list of init functions. */ -static GList *timeout_functions = NULL; /* A list of timeout functions sorted by - * when the length of the time interval - * remaining. Therefore, the first timeout - * function to expire is at the head of - * the list and the last to expire is at - * the tail of the list. - */ -static GList *idle_functions = NULL; /* A list of idle functions. +static GList *quit_functions = NULL; /* A list of quit functions. */ - -static GList *current_idles = NULL; -static GList *current_timeouts = NULL; -static GMemChunk *timeout_mem_chunk = NULL; -static GMemChunk *idle_mem_chunk = NULL; +static GMemChunk *quit_mem_chunk = NULL; static GSList *key_snoopers = NULL; @@ -144,86 +133,245 @@ static GdkColormap *gtk_colormap; /* The colormap to be used in creating new guint gtk_debug_flags = 0; /* Global GTK debug flag */ #ifdef G_ENABLE_DEBUG -static GDebugKey gtk_debug_keys[] = { - {"objects", GTK_DEBUG_OBJECTS} +static const GDebugKey gtk_debug_keys[] = { + {"objects", GTK_DEBUG_OBJECTS}, + {"misc", GTK_DEBUG_MISC}, + {"signals", GTK_DEBUG_SIGNALS}, + {"dnd", GTK_DEBUG_DND} }; -static const int gtk_ndebug_keys = sizeof(gtk_debug_keys)/sizeof(GDebugKey); +static const guint gtk_ndebug_keys = sizeof (gtk_debug_keys) / sizeof (GDebugKey); #endif /* G_ENABLE_DEBUG */ - +gchar* +gtk_check_version (guint required_major, + guint required_minor, + guint required_micro) +{ + if (required_major > GTK_MAJOR_VERSION) + return "Gtk+ version too old (major mismatch)"; + if (required_major < GTK_MAJOR_VERSION) + return "Gtk+ version too new (major mismatch)"; + if (required_minor > GTK_MINOR_VERSION) + return "Gtk+ version too old (minor mismatch)"; + if (required_minor < GTK_MINOR_VERSION) + return "Gtk+ version too new (minor mismatch)"; + if (required_micro < GTK_MICRO_VERSION - GTK_BINARY_AGE) + return "Gtk+ version too new (micro mismatch)"; + if (required_micro > GTK_MICRO_VERSION) + return "Gtk+ version too old (micro mismatch)"; + return NULL; +} void gtk_init (int *argc, char ***argv) { - if (0) - { - g_set_error_handler (gtk_error); - g_set_warning_handler (gtk_warning); - g_set_message_handler (gtk_message); - g_set_print_handler (gtk_print); - } + GSList *gtk_modules = NULL; + GSList *slist; + gchar *env_string = NULL; + + if (gtk_initialized) + return; + + /* There is some argument for putting this in a separate + * function ... but I don't think that it is much + * of a restriction to require that GTK+ be used + * single threaded until gtk_init(). + */ + +#if 0 + g_set_error_handler (gtk_error); + g_set_warning_handler (gtk_warning); + g_set_message_handler (gtk_message); + g_set_print_handler (gtk_print); +#endif /* Initialize "gdk". We pass along the 'argc' and 'argv' * parameters as they contain information that GDK uses */ gdk_init (argc, argv); + + gdk_event_handler_set ((GdkEventFunc)gtk_main_do_event, NULL, NULL); #ifdef G_ENABLE_DEBUG - { - gchar *debug_string = getenv("GTK_DEBUG"); - if (debug_string != NULL) - gtk_debug_flags = g_parse_debug_string (debug_string, + env_string = getenv ("GTK_DEBUG"); + if (env_string != NULL) + { + gtk_debug_flags = g_parse_debug_string (env_string, gtk_debug_keys, gtk_ndebug_keys); - } + env_string = NULL; + } +#endif /* G_ENABLE_DEBUG */ + + env_string = getenv ("GTK_MODULES"); + if (env_string) + { + gchar **modules, **as; + + modules = g_strsplit (env_string, ":", -1); + for (as = modules; *as; as++) + { + if (**as) + gtk_modules = g_slist_prepend (gtk_modules, *as); + else + g_free (*as); + } + g_free (modules); + env_string = NULL; + } if (argc && argv) { - gint i; + gint i, j, k; for (i = 1; i < *argc;) { - if ((*argv)[i] == NULL) + if (strcmp ("--gtk-module", (*argv)[i]) == 0 || + strncmp ("--gtk-module=", (*argv)[i], 13) == 0) { - i += 1; - continue; - } + gchar *module_name = (*argv)[i] + 12; + + if (*module_name == '=') + module_name++; + else + { + (*argv)[i] = NULL; + i += 1; + module_name = (*argv)[i]; + } + (*argv)[i] = NULL; - if (strcmp ("--gtk-debug", (*argv)[i]) == 0) + gtk_modules = g_slist_prepend (gtk_modules, g_strdup (module_name)); + } + else if (strcmp ("--g-fatal-warnings", (*argv)[i]) == 0) { + GLogLevelFlags fatal_mask; + + fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK); + fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL; + g_log_set_always_fatal (fatal_mask); (*argv)[i] = NULL; - - if ((i + 1) < *argc && (*argv)[i + 1]) + } +#ifdef G_ENABLE_DEBUG + else if ((strcmp ("--gtk-debug", (*argv)[i]) == 0) || + (strncmp ("--gtk-debug=", (*argv)[i], 12) == 0)) + { + gchar *equal_pos = strchr ((*argv)[i], '='); + + if (equal_pos != NULL) + { + gtk_debug_flags |= g_parse_debug_string (equal_pos+1, + gtk_debug_keys, + gtk_ndebug_keys); + } + else if ((i + 1) < *argc && (*argv)[i + 1]) { gtk_debug_flags |= g_parse_debug_string ((*argv)[i+1], gtk_debug_keys, gtk_ndebug_keys); - (*argv)[i + 1] = NULL; + (*argv)[i] = NULL; i += 1; } + (*argv)[i] = NULL; } - else if (strcmp ("--gtk-no-debug", (*argv)[i]) == 0) + else if ((strcmp ("--gtk-no-debug", (*argv)[i]) == 0) || + (strncmp ("--gtk-no-debug=", (*argv)[i], 15) == 0)) { - (*argv)[i] = NULL; - - if ((i + 1) < *argc && (*argv)[i + 1]) + gchar *equal_pos = strchr ((*argv)[i], '='); + + if (equal_pos != NULL) + { + gtk_debug_flags &= ~g_parse_debug_string (equal_pos+1, + gtk_debug_keys, + gtk_ndebug_keys); + } + else if ((i + 1) < *argc && (*argv)[i + 1]) { gtk_debug_flags &= ~g_parse_debug_string ((*argv)[i+1], gtk_debug_keys, gtk_ndebug_keys); - (*argv)[i + 1] = NULL; + (*argv)[i] = NULL; i += 1; } + (*argv)[i] = NULL; } +#endif /* G_ENABLE_DEBUG */ i += 1; } + + for (i = 1; i < *argc; i++) + { + for (k = i; k < *argc; k++) + if ((*argv)[k] != NULL) + break; + + if (k > i) + { + k -= i; + for (j = i + k; j < *argc; j++) + (*argv)[j-k] = (*argv)[j]; + *argc -= k; + } + } + } + + /* load gtk modules */ + gtk_modules = g_slist_reverse (gtk_modules); + for (slist = gtk_modules; slist; slist = slist->next) + { + gchar *module_name; + GModule *module = NULL; + GtkModuleInitFunc modinit_func = NULL; + + module_name = slist->data; + slist->data = NULL; + if (!(module_name[0] == '/' || + (module_name[0] == 'l' && + module_name[1] == 'i' && + module_name[2] == 'b'))) + { + gchar *old = module_name; + + module_name = g_strconcat ("lib", module_name, ".so", NULL); + g_free (old); + } + if (g_module_supported ()) + { + module = g_module_open (module_name, G_MODULE_BIND_LAZY); + if (module && + g_module_symbol (module, "gtk_module_init", (gpointer*) &modinit_func) && + modinit_func) + { + if (!g_slist_find (gtk_modules, modinit_func)) + { + g_module_make_resident (module); + slist->data = modinit_func; + } + else + { + g_module_close (module); + module = NULL; + } + } + } + if (!modinit_func) + { + g_warning ("Failed to load module \"%s\": %s", + module ? g_module_name (module) : module_name, + g_module_error ()); + if (module) + g_module_close (module); + } + g_free (module_name); } -#endif /* G_ENABLE_DEBUG */ +#ifdef ENABLE_NLS + bindtextdomain("gtk+",GTK_LOCALEDIR); +#endif /* Initialize the default visual and colormap to be * used in creating widgets. (We want to use the system @@ -231,18 +379,33 @@ gtk_init (int *argc, */ gtk_visual = gdk_visual_get_system (); gtk_colormap = gdk_colormap_get_system (); + + gtk_type_init (); + gtk_signal_init (); gtk_rc_init (); - gtk_type_init (); /* Register an exit function to make sure we are able to cleanup. */ - if (ATEXIT (gtk_exit_func)) - g_warning ("unable to register exit function"); + g_atexit (gtk_exit_func); /* Set the 'initialized' flag. */ - initialized = TRUE; + gtk_initialized = TRUE; + + /* initialize gtk modules + */ + for (slist = gtk_modules; slist; slist = slist->next) + { + if (slist->data) + { + GtkModuleInitFunc modinit; + + modinit = slist->data; + modinit (argc, argv); + } + } + g_slist_free (gtk_modules); } void @@ -257,21 +420,24 @@ gtk_exit (int errorcode) } gchar* -gtk_set_locale () +gtk_set_locale (void) { return gdk_set_locale (); } void -gtk_main () +gtk_main (void) { GList *tmp_list; GList *functions; GtkInitFunction *init; - int old_done; - - main_level++; + GMainLoop *loop; + + gtk_main_loop_level++; + loop = g_main_new (TRUE); + main_loops = g_slist_prepend (main_loops, loop); + tmp_list = functions = init_functions; init_functions = NULL; @@ -283,275 +449,325 @@ gtk_main () (* init->function) (init->data); g_free (init); } - g_list_free (functions); - - old_done = iteration_done; - while (!gtk_main_iteration ()) - ; - iteration_done = old_done; - - main_level--; + + if (g_main_is_running (main_loops->data)) + { + GDK_THREADS_LEAVE (); + g_main_run (loop); + GDK_THREADS_ENTER (); + gdk_flush (); + } + + if (quit_functions) + { + GList *reinvoke_list = NULL; + GtkQuitFunction *quitf; + + while (quit_functions) + { + quitf = quit_functions->data; + + quit_functions = g_list_remove_link (quit_functions, quit_functions); + + if ((quitf->main_level && quitf->main_level != gtk_main_loop_level) || + gtk_quit_invoke_function (quitf)) + { + reinvoke_list = g_list_prepend (reinvoke_list, quitf); + } + else + { + g_list_free (tmp_list); + gtk_quit_destroy (quitf); + } + } + if (reinvoke_list) + { + GList *work; + + work = g_list_last (reinvoke_list); + if (quit_functions) + quit_functions->prev = work; + work->next = quit_functions; + quit_functions = work; + } + + gdk_flush (); + } + + main_loops = g_slist_remove (main_loops, loop); + + g_main_destroy (loop); + + gtk_main_loop_level--; } guint gtk_main_level (void) { - return main_level; + return gtk_main_loop_level; } void -gtk_main_quit () +gtk_main_quit (void) { - iteration_done = TRUE; + g_return_if_fail (main_loops != NULL); + + g_main_quit (main_loops->data); } gint gtk_events_pending (void) { - return gdk_events_pending() + (next_event != NULL) ? 1 : 0; + return g_main_pending(); } gint -gtk_main_iteration () +gtk_main_iteration (void) { - return gtk_main_iteration_do (TRUE); + g_main_iteration (TRUE); + + if (main_loops) + return !g_main_is_running (main_loops->data); + else + return TRUE; } -gint +gint gtk_main_iteration_do (gboolean blocking) +{ + g_main_iteration (blocking); + + if (main_loops) + return !g_main_is_running (main_loops->data); + else + return TRUE; +} + +void +gtk_main_do_event (GdkEvent *event) { GtkWidget *event_widget; GtkWidget *grab_widget; - GdkEvent *event = NULL; + GdkEvent *next_event; GList *tmp_list; - - iteration_done = FALSE; - - /* If this is a recursive call, and there are pending timeouts or - * idles, finish them, then return immediately to avoid blocking - * in gdk_event_get() + + /* If there are any events pending then get the next one. */ - if (current_timeouts) - { - gtk_handle_current_timeouts( gdk_time_get()); - return iteration_done; - } - if (current_idles) - { - gtk_handle_current_idles(); - return iteration_done; - } + next_event = gdk_event_peek (); - /* If there is a valid event in 'next_event' then move it to 'event' + /* Try to compress enter/leave notify events. These event + * pairs occur when the mouse is dragged quickly across + * a window with many buttons (or through a menu). Instead + * of highlighting and de-highlighting each widget that + * is crossed it is better to simply de-highlight the widget + * which contained the mouse initially and highlight the + * widget which ends up containing the mouse. */ if (next_event) + if (((event->type == GDK_ENTER_NOTIFY) || + (event->type == GDK_LEAVE_NOTIFY)) && + ((next_event->type == GDK_ENTER_NOTIFY) || + (next_event->type == GDK_LEAVE_NOTIFY)) && + (next_event->type != event->type) && + (next_event->any.window == event->any.window)) + { + /* Throw both the peeked copy and the queued copy away + */ + gdk_event_free (next_event); + next_event = gdk_event_get (); + gdk_event_free (next_event); + + return; + } + + if (next_event) + gdk_event_free (next_event); + + /* Find the widget which got the event. We store the widget + * in the user_data field of GdkWindow's. + * Ignore the event if we don't have a widget for it, except + * for GDK_PROPERTY_NOTIFY events which are handled specialy. + * Though this happens rarely, bogus events can occour + * for e.g. destroyed GdkWindows. + */ + event_widget = gtk_get_event_widget (event); + if (!event_widget) { - event = next_event; - next_event = NULL; + /* To handle selection INCR transactions, we select + * PropertyNotify events on the requestor window and create + * a corresponding (fake) GdkWindow so that events get + * here. There won't be a widget though, so we have to handle + * them specially + */ + if (event->type == GDK_PROPERTY_NOTIFY) + gtk_selection_incr_event (event->any.window, + &event->property); + + return; } - /* If we don't have an event then get one. + /* Push the event onto a stack of current events for + * gtk_current_event_get(). */ - if (!event) + current_events = g_list_prepend (current_events, event); + + /* If there is a grab in effect... + */ + if (grabs) { - /* Handle setting of the "gdk" timer. If there are no - * timeout functions, then the timer is turned off. - * If there are timeout functions, then the timer is - * set to the shortest timeout interval (which is - * the first timeout function). - */ - gtk_handle_timer (); + grab_widget = grabs->data; - if (blocking) event = gdk_event_get (); + /* If the grab widget is an ancestor of the event widget + * then we send the event to the original event widget. + * This is the key to implementing modality. + */ + if (GTK_WIDGET_IS_SENSITIVE (event_widget) && + gtk_widget_is_ancestor (event_widget, grab_widget)) + grab_widget = event_widget; } - - /* "gdk_event_get" can return FALSE if the timer goes off - * and no events are pending. Therefore, we should make - * sure that we got an event before continuing. + else + { + grab_widget = event_widget; + } + + /* Not all events get sent to the grabbing widget. + * The delete, destroy, expose, focus change and resize + * events still get sent to the event widget because + * 1) these events have no meaning for the grabbing widget + * and 2) redirecting these events to the grabbing widget + * could cause the display to be messed up. + * + * Drag events are also not redirected, since it isn't + * clear what the semantics of that would be. */ - if (event) + switch (event->type) { - /* If there are any events pending then get the next one. - */ - if (gdk_events_pending () > 0) - next_event = gdk_event_get (); + case GDK_NOTHING: + break; - /* Try to compress enter/leave notify events. These event - * pairs occur when the mouse is dragged quickly across - * a window with many buttons (or through a menu). Instead - * of highlighting and de-highlighting each widget that - * is crossed it is better to simply de-highlight the widget - * which contained the mouse initially and highlight the - * widget which ends up containing the mouse. - */ - if (next_event) - if (((event->type == GDK_ENTER_NOTIFY) || - (event->type == GDK_LEAVE_NOTIFY)) && - ((next_event->type == GDK_ENTER_NOTIFY) || - (next_event->type == GDK_LEAVE_NOTIFY)) && - (next_event->type != event->type) && - (next_event->any.window == event->any.window)) - { - gdk_event_free (event); - gdk_event_free (next_event); - next_event = NULL; - - goto event_handling_done; - } + case GDK_DELETE: + gtk_widget_ref (event_widget); + if (!gtk_widget_event (event_widget, event) && + !GTK_OBJECT_DESTROYED (event_widget)) + gtk_widget_destroy (event_widget); + gtk_widget_unref (event_widget); + break; - /* Find the widget which got the event. We store the widget - * in the user_data field of GdkWindow's. - * Ignore the event if we don't have a widget for it, except - * for GDK_PROPERTY_NOTIFY events which are handled specialy. - * Though this happens rarely, bogus events can occour - * for e.g. destroyed GdkWindows. - */ - event_widget = gtk_get_event_widget (event); - if (!event_widget) + case GDK_DESTROY: + gtk_widget_ref (event_widget); + gtk_widget_event (event_widget, event); + if (!GTK_OBJECT_DESTROYED (event_widget)) + gtk_widget_destroy (event_widget); + gtk_widget_unref (event_widget); + break; + + case GDK_PROPERTY_NOTIFY: + case GDK_EXPOSE: + case GDK_NO_EXPOSE: + case GDK_FOCUS_CHANGE: + case GDK_CONFIGURE: + case GDK_MAP: + case GDK_UNMAP: + case GDK_SELECTION_CLEAR: + case GDK_SELECTION_REQUEST: + case GDK_SELECTION_NOTIFY: + case GDK_CLIENT_EVENT: + case GDK_VISIBILITY_NOTIFY: + gtk_widget_event (event_widget, event); + break; + + case GDK_BUTTON_PRESS: + case GDK_2BUTTON_PRESS: + case GDK_3BUTTON_PRESS: + /* We treat button 4-5 specially, assume we have + * a MS-style scrollwheel mouse, and try to find + * a plausible widget to scroll. We also trap + * button 4-5 double and triple clicks here, since + * they will be generated if the user scrolls quickly. + */ + if ((grab_widget == event_widget) && + (event->button.button == 4 || event->button.button == 5)) { - /* To handle selection INCR transactions, we select - * PropertyNotify events on the requestor window and create - * a corresponding (fake) GdkWindow so that events get - * here. There won't be a widget though, so we have to handle - * them specially - */ - if (event->type == GDK_PROPERTY_NOTIFY) - gtk_selection_incr_event (event->any.window, - &event->property); + GtkWidget *range = NULL; + GtkWidget *scrollwin; - gdk_event_free (event); + if (GTK_IS_RANGE (event_widget)) + range = event_widget; + else + { + scrollwin = gtk_widget_get_ancestor (event_widget, + GTK_TYPE_SCROLLED_WINDOW); + if (scrollwin) + range = GTK_SCROLLED_WINDOW (scrollwin)->vscrollbar; + } - goto event_handling_done; + if (range && GTK_WIDGET_VISIBLE (range)) + { + if (event->type == GDK_BUTTON_PRESS) + { + GtkAdjustment *adj = GTK_RANGE (range)->adjustment; + gfloat new_value = adj->value + ((event->button.button == 4) ? + -adj->page_increment / 2: + adj->page_increment / 2); + new_value = CLAMP (new_value, adj->lower, adj->upper - adj->page_size); + gtk_adjustment_set_value (adj, new_value); + } + break; + } } - - /* Push the event onto a stack of current events for - * gtk_current_event_get(). - */ - current_events = g_list_prepend (current_events, event); - - /* If there is a grab in effect... - */ - if (grabs) + gtk_propagate_event (grab_widget, event); + break; + + case GDK_KEY_PRESS: + case GDK_KEY_RELEASE: + if (key_snoopers) { - grab_widget = grabs->data; - - /* If the grab widget is an ancestor of the event widget - * then we send the event to the original event widget. - * This is the key to implementing modality. - */ - if (gtk_widget_is_ancestor (event_widget, grab_widget)) - grab_widget = event_widget; + if (gtk_invoke_key_snoopers (grab_widget, event)) + break; } - else + /* else fall through */ + case GDK_MOTION_NOTIFY: + case GDK_BUTTON_RELEASE: + case GDK_PROXIMITY_IN: + case GDK_PROXIMITY_OUT: + gtk_propagate_event (grab_widget, event); + break; + + case GDK_ENTER_NOTIFY: + if (GTK_WIDGET_IS_SENSITIVE (grab_widget)) { - grab_widget = event_widget; + gtk_widget_event (grab_widget, event); + if (event_widget == grab_widget) + GTK_PRIVATE_SET_FLAG (event_widget, GTK_LEAVE_PENDING); } - - /* Not all events get sent to the grabbing widget. - * The delete, destroy, expose, focus change and resize - * events still get sent to the event widget because - * 1) these events have no meaning for the grabbing widget - * and 2) redirecting these events to the grabbing widget - * could cause the display to be messed up. - */ - switch (event->type) + break; + + case GDK_LEAVE_NOTIFY: + if (GTK_WIDGET_LEAVE_PENDING (event_widget)) { - case GDK_NOTHING: - break; - - case GDK_DELETE: - gtk_widget_ref (event_widget); - if (gtk_widget_event (event_widget, event)) - gtk_widget_destroy (event_widget); - gtk_widget_unref (event_widget); - break; - - case GDK_DESTROY: - gtk_widget_ref (event_widget); - gtk_widget_event (event_widget, event); - gtk_widget_destroy (event_widget); - gtk_widget_unref (event_widget); - break; - - case GDK_PROPERTY_NOTIFY: - case GDK_EXPOSE: - case GDK_NO_EXPOSE: - case GDK_FOCUS_CHANGE: - case GDK_CONFIGURE: - case GDK_MAP: - case GDK_UNMAP: - case GDK_SELECTION_CLEAR: - case GDK_SELECTION_REQUEST: - case GDK_SELECTION_NOTIFY: - case GDK_CLIENT_EVENT: - case GDK_DRAG_BEGIN: - case GDK_DRAG_REQUEST: - case GDK_DROP_ENTER: - case GDK_DROP_LEAVE: - case GDK_DROP_DATA_AVAIL: - case GDK_VISIBILITY_NOTIFY: + GTK_PRIVATE_UNSET_FLAG (event_widget, GTK_LEAVE_PENDING); gtk_widget_event (event_widget, event); - break; - - case GDK_KEY_PRESS: - case GDK_KEY_RELEASE: - if (key_snoopers) - { - if (gtk_invoke_key_snoopers (grab_widget, event)) - break; - } - /* else fall through */ - case GDK_MOTION_NOTIFY: - case GDK_BUTTON_PRESS: - case GDK_2BUTTON_PRESS: - case GDK_3BUTTON_PRESS: - case GDK_BUTTON_RELEASE: - case GDK_PROXIMITY_IN: - case GDK_PROXIMITY_OUT: - case GDK_OTHER_EVENT: - gtk_propagate_event (grab_widget, event); - break; - - case GDK_ENTER_NOTIFY: - if (GTK_WIDGET_IS_SENSITIVE (grab_widget)) - { - gtk_widget_event (grab_widget, event); - if (event_widget == grab_widget) - GTK_PRIVATE_SET_FLAG (event_widget, GTK_LEAVE_PENDING); - } - break; - - case GDK_LEAVE_NOTIFY: - if (GTK_WIDGET_LEAVE_PENDING (event_widget)) - { - GTK_PRIVATE_UNSET_FLAG (event_widget, GTK_LEAVE_PENDING); - gtk_widget_event (event_widget, event); - } - else if (GTK_WIDGET_IS_SENSITIVE (grab_widget)) - gtk_widget_event (grab_widget, event); - break; } + else if (GTK_WIDGET_IS_SENSITIVE (grab_widget)) + gtk_widget_event (grab_widget, event); + break; - tmp_list = current_events; - current_events = g_list_remove_link (current_events, tmp_list); - g_list_free_1 (tmp_list); - - gdk_event_free (event); - } - else - { - if (gdk_events_pending() == 0) - gtk_handle_idle (); + case GDK_DRAG_STATUS: + case GDK_DROP_FINISHED: + gtk_drag_source_handle_event (event_widget, event); + break; + case GDK_DRAG_ENTER: + case GDK_DRAG_LEAVE: + case GDK_DRAG_MOTION: + case GDK_DROP_START: + gtk_drag_dest_handle_event (event_widget, event); + break; } -event_handling_done: - - /* Handle timeout functions that may have expired. - */ - gtk_handle_timeouts (); - - return iteration_done; + tmp_list = current_events; + current_events = g_list_remove_link (current_events, tmp_list); + g_list_free_1 (tmp_list); } gint @@ -615,9 +831,9 @@ gtk_init_add (GtkFunction function, init_functions = g_list_prepend (init_functions, init); } -gint +guint gtk_key_snooper_install (GtkKeySnoopFunc snooper, - gpointer func_data) + gpointer func_data) { GtkKeySnooperData *data; static guint snooper_id = 1; @@ -634,7 +850,7 @@ gtk_key_snooper_install (GtkKeySnoopFunc snooper, } void -gtk_key_snooper_remove (gint snooper_id) +gtk_key_snooper_remove (guint snooper_id) { GtkKeySnooperData *data = NULL; GSList *slist; @@ -673,104 +889,122 @@ gtk_invoke_key_snoopers (GtkWidget *grab_widget, return return_val; } -gint -gtk_timeout_add_full (guint32 interval, - GtkFunction function, - GtkCallbackMarshal marshal, - gpointer data, - GtkDestroyNotify destroy) +guint +gtk_quit_add_full (guint main_level, + GtkFunction function, + GtkCallbackMarshal marshal, + gpointer data, + GtkDestroyNotify destroy) { - static gint timeout_tag = 1; - GtkTimeoutFunction *timeoutf; + static guint quit_id = 1; + GtkQuitFunction *quitf; g_return_val_if_fail ((function != NULL) || (marshal != NULL), 0); - /* Create a new timeout function structure. - * The start time is the current time. - */ - if (!timeout_mem_chunk) - timeout_mem_chunk = g_mem_chunk_new ("timeout mem chunk", sizeof (GtkTimeoutFunction), - 1024, G_ALLOC_AND_FREE); + if (!quit_mem_chunk) + quit_mem_chunk = g_mem_chunk_new ("quit mem chunk", sizeof (GtkQuitFunction), + 512, G_ALLOC_AND_FREE); - timeoutf = g_chunk_new (GtkTimeoutFunction, timeout_mem_chunk); + quitf = g_chunk_new (GtkQuitFunction, quit_mem_chunk); - timeoutf->tag = timeout_tag++; - timeoutf->start = gdk_time_get (); - timeoutf->interval = interval; - timeoutf->originterval = interval; - timeoutf->function = function; - timeoutf->marshal = marshal; - timeoutf->data = data; - timeoutf->destroy = destroy; + quitf->id = quit_id++; + quitf->main_level = main_level; + quitf->function = function; + quitf->marshal = marshal; + quitf->data = data; + quitf->destroy = destroy; + + quit_functions = g_list_prepend (quit_functions, quitf); - gtk_timeout_insert (timeoutf); - - return timeoutf->tag; + return quitf->id; } static void -gtk_timeout_destroy (GtkTimeoutFunction *timeoutf) +gtk_quit_destroy (GtkQuitFunction *quitf) { - if (timeoutf->destroy) - (timeoutf->destroy) (timeoutf->data); - g_mem_chunk_free (timeout_mem_chunk, timeoutf); + if (quitf->destroy) + quitf->destroy (quitf->data); + g_mem_chunk_free (quit_mem_chunk, quitf); } -gint -gtk_timeout_add (guint32 interval, - GtkFunction function, - gpointer data) +static gint +gtk_quit_destructor (GtkObject **object_p) { - return gtk_timeout_add_full (interval, function, FALSE, data, NULL); + if (*object_p) + gtk_object_destroy (*object_p); + g_free (object_p); + + return FALSE; } -gint -gtk_timeout_add_interp (guint32 interval, - GtkCallbackMarshal function, - gpointer data, - GtkDestroyNotify destroy) +void +gtk_quit_add_destroy (guint main_level, + GtkObject *object) +{ + GtkObject **object_p; + + g_return_if_fail (main_level > 0); + g_return_if_fail (object != NULL); + g_return_if_fail (GTK_IS_OBJECT (object)); + + object_p = g_new (GtkObject*, 1); + *object_p = object; + gtk_signal_connect (object, + "destroy", + GTK_SIGNAL_FUNC (gtk_widget_destroyed), + object_p); + gtk_quit_add (main_level, (GtkFunction) gtk_quit_destructor, object_p); +} + +guint +gtk_quit_add (guint main_level, + GtkFunction function, + gpointer data) { - return gtk_timeout_add_full (interval, NULL, function, data, destroy); + return gtk_quit_add_full (main_level, function, NULL, data, NULL); } void -gtk_timeout_remove (gint tag) +gtk_quit_remove (guint id) { - GtkTimeoutFunction *timeoutf; + GtkQuitFunction *quitf; GList *tmp_list; - /* Remove a timeout function. - * (Which, basically, involves searching the - * list for the tag). - */ - tmp_list = timeout_functions; + tmp_list = quit_functions; while (tmp_list) { - timeoutf = tmp_list->data; + quitf = tmp_list->data; - if (timeoutf->tag == tag) + if (quitf->id == id) { - timeout_functions = g_list_remove_link (timeout_functions, tmp_list); + quit_functions = g_list_remove_link (quit_functions, tmp_list); g_list_free (tmp_list); - gtk_timeout_destroy (timeoutf); + gtk_quit_destroy (quitf); return; } tmp_list = tmp_list->next; } +} + +void +gtk_quit_remove_by_data (gpointer data) +{ + GtkQuitFunction *quitf; + GList *tmp_list; - tmp_list = current_timeouts; + tmp_list = quit_functions; while (tmp_list) { - timeoutf = tmp_list->data; + quitf = tmp_list->data; - if (timeoutf->tag == tag) + if (quitf->data == data) { - current_timeouts = g_list_remove_link (current_timeouts, tmp_list); + quit_functions = g_list_remove_link (quit_functions, tmp_list); g_list_free (tmp_list); - gtk_timeout_destroy (timeoutf); - + gtk_quit_destroy (quitf); + return; } @@ -778,228 +1012,177 @@ gtk_timeout_remove (gint tag) } } -/* We rely on some knowledge of how g_list_insert_sorted works to make - * sure that we insert at the _end_ of the idles of this priority - */ -static gint -gtk_idle_compare (gpointer a, gpointer b) +guint +gtk_timeout_add_full (guint32 interval, + GtkFunction function, + GtkCallbackMarshal marshal, + gpointer data, + GtkDestroyNotify destroy) { - return (((GtkIdleFunction *)a)->priority < ((GtkIdleFunction *)b)->priority) - ? -1 : 1; + if (marshal) + { + GtkClosure *closure; + + closure = g_new (GtkClosure, 1); + closure->marshal = marshal; + closure->data = data; + closure->destroy = destroy; + + return g_timeout_add_full (0, interval, + gtk_invoke_idle_timeout, + closure, + gtk_destroy_closure); + } + else + return g_timeout_add_full (0, interval, function, data, destroy); } -gint -gtk_idle_add_full (gint priority, - GtkFunction function, - GtkCallbackMarshal marshal, - gpointer data, - GtkDestroyNotify destroy) +guint +gtk_timeout_add (guint32 interval, + GtkFunction function, + gpointer data) { - static gint idle_tag = 1; - GtkIdleFunction *idlef; - - g_return_val_if_fail ((function != NULL) || (marshal != NULL), 0); - - if (!idle_mem_chunk) - idle_mem_chunk = g_mem_chunk_new ("idle mem chunk", sizeof (GtkIdleFunction), - 1024, G_ALLOC_AND_FREE); - - idlef = g_chunk_new (GtkIdleFunction, idle_mem_chunk); - - idlef->tag = idle_tag++; - idlef->priority = priority; - idlef->function = function; - idlef->marshal = marshal; - idlef->data = data; - idlef->destroy = destroy; - - idle_functions = g_list_insert_sorted (idle_functions, idlef, gtk_idle_compare); - - return idlef->tag; + return g_timeout_add_full (0, interval, function, data, NULL); } -gint -gtk_idle_add_interp (GtkCallbackMarshal marshal, - gpointer data, - GtkDestroyNotify destroy) +void +gtk_timeout_remove (guint tag) { - return gtk_idle_add_full (GTK_PRIORITY_DEFAULT, NULL, marshal, data, destroy); + g_source_remove (tag); } -static void -gtk_idle_destroy (GtkIdleFunction *idlef) +guint +gtk_idle_add_full (gint priority, + GtkFunction function, + GtkCallbackMarshal marshal, + gpointer data, + GtkDestroyNotify destroy) { - if (idlef->destroy) - idlef->destroy (idlef->data); - g_mem_chunk_free (idle_mem_chunk, idlef); + if (marshal) + { + GtkClosure *closure; + + closure = g_new (GtkClosure, 1); + closure->marshal = marshal; + closure->data = data; + closure->destroy = destroy; + + return g_idle_add_full (priority, + gtk_invoke_idle_timeout, + closure, + gtk_destroy_closure); + } + else + return g_idle_add_full (priority, function, data, destroy); } -gint +guint gtk_idle_add (GtkFunction function, gpointer data) { - return gtk_idle_add_full (GTK_PRIORITY_DEFAULT, function, NULL, data, NULL); + return g_idle_add_full (GTK_PRIORITY_DEFAULT, function, data, NULL); } -gint -gtk_idle_add_priority (gint priority, - GtkFunction function, - gpointer data) +guint +gtk_idle_add_priority (gint priority, + GtkFunction function, + gpointer data) { - return gtk_idle_add_full (priority, function, NULL, data, NULL); + return g_idle_add_full (priority, function, data, NULL); } void -gtk_idle_remove (gint tag) +gtk_idle_remove (guint tag) { - GtkIdleFunction *idlef; - GList *tmp_list; - - tmp_list = idle_functions; - while (tmp_list) - { - idlef = tmp_list->data; - - if (idlef->tag == tag) - { - idle_functions = g_list_remove_link (idle_functions, tmp_list); - g_list_free (tmp_list); - gtk_idle_destroy (idlef); - - return; - } - - tmp_list = tmp_list->next; - } - - tmp_list = current_idles; - while (tmp_list) - { - idlef = tmp_list->data; - - if (idlef->tag == tag) - { - current_idles = g_list_remove_link (current_idles, tmp_list); - g_list_free (tmp_list); - gtk_idle_destroy (idlef); - - return; - } - - tmp_list = tmp_list->next; - } + g_source_remove (tag); } void gtk_idle_remove_by_data (gpointer data) { - GtkIdleFunction *idlef; - GList *tmp_list; - - tmp_list = idle_functions; - while (tmp_list) - { - idlef = tmp_list->data; - - if (idlef->data == data) - { - idle_functions = g_list_remove_link (idle_functions, tmp_list); - g_list_free (tmp_list); - g_mem_chunk_free (idle_mem_chunk, idlef); - - return; - } - - tmp_list = tmp_list->next; - } - - tmp_list = current_idles; - while (tmp_list) - { - idlef = tmp_list->data; - - if (idlef->data == data) - { - current_idles = g_list_remove_link (current_idles, tmp_list); - g_list_free (tmp_list); - g_mem_chunk_free (idle_mem_chunk, idlef); - - return; - } - - tmp_list = tmp_list->next; - } -} - -static void -gtk_invoke_input_function (GtkInputFunction *input, - gint source, - GdkInputCondition condition) -{ - GtkArg args[3]; - args[0].type = GTK_TYPE_INT; - args[0].name = NULL; - GTK_VALUE_INT(args[0]) = source; - args[1].type = GTK_TYPE_GDK_INPUT_CONDITION; - args[1].name = NULL; - GTK_VALUE_FLAGS(args[1]) = condition; - args[2].type = GTK_TYPE_NONE; - args[2].name = NULL; - - input->callback (NULL, input->data, 2, args); + if (!g_idle_remove_by_data (data)) + g_warning ("gtk_idle_remove_by_data(%p): no such idle", data); } -static void -gtk_destroy_input_function (GtkInputFunction *input) -{ - if (input->destroy) - (input->destroy) (input->data); - g_free (input); -} - -gint -gtk_input_add_full (gint source, - GdkInputCondition condition, - GdkInputFunction function, - GtkCallbackMarshal marshal, - gpointer data, - GtkDestroyNotify destroy) +guint +gtk_input_add_full (gint source, + GdkInputCondition condition, + GdkInputFunction function, + GtkCallbackMarshal marshal, + gpointer data, + GtkDestroyNotify destroy) { if (marshal) { - GtkInputFunction *input = g_new (GtkInputFunction, 1); - input->callback = marshal; - input->data = data; - input->destroy = destroy; + GtkClosure *closure; + + closure = g_new (GtkClosure, 1); + closure->marshal = marshal; + closure->data = data; + closure->destroy = destroy; return gdk_input_add_full (source, condition, - (GdkInputFunction) gtk_invoke_input_function, - input, - (GdkDestroyNotify) gtk_destroy_input_function); + (GdkInputFunction) gtk_invoke_input, + closure, + (GdkDestroyNotify) gtk_destroy_closure); } else return gdk_input_add_full (source, condition, function, data, destroy); } -gint -gtk_input_add_interp (gint source, - GdkInputCondition condition, - GtkCallbackMarshal callback, - gpointer data, - GtkDestroyNotify destroy) +void +gtk_input_remove (guint tag) { - return gdk_input_add_full (source, condition, NULL, callback, data); + g_source_remove (tag); } -void -gtk_input_remove (gint tag) +static void +gtk_destroy_closure (gpointer data) +{ + GtkClosure *closure = data; + + if (closure->destroy) + (closure->destroy) (closure->data); + g_free (closure); +} + +static gboolean +gtk_invoke_idle_timeout (gpointer data) { - gdk_input_remove (tag); + GtkClosure *closure = data; + + GtkArg args[1]; + gint ret_val = FALSE; + args[0].name = NULL; + args[0].type = GTK_TYPE_BOOL; + args[0].d.pointer_data = &ret_val; + closure->marshal (NULL, closure->data, 0, args); + return ret_val; +} + +static void +gtk_invoke_input (gpointer data, + gint source, + GdkInputCondition condition) +{ + GtkClosure *closure = data; + + GtkArg args[3]; + args[0].type = GTK_TYPE_INT; + args[0].name = NULL; + GTK_VALUE_INT(args[0]) = source; + args[1].type = GTK_TYPE_GDK_INPUT_CONDITION; + args[1].name = NULL; + GTK_VALUE_FLAGS(args[1]) = condition; + args[2].type = GTK_TYPE_NONE; + args[2].name = NULL; + + closure->marshal (NULL, closure->data, 2, args); } -GdkEvent * -gtk_get_current_event () +GdkEvent* +gtk_get_current_event (void) { if (current_events) return gdk_event_copy ((GdkEvent *) current_events->data); @@ -1013,307 +1196,92 @@ gtk_get_event_widget (GdkEvent *event) GtkWidget *widget; widget = NULL; - if (event->any.window) + if (event && event->any.window) gdk_window_get_user_data (event->any.window, (void**) &widget); return widget; } static void -gtk_exit_func () +gtk_exit_func (void) { - if (initialized) + if (gtk_initialized) { - initialized = FALSE; + gtk_initialized = FALSE; gtk_preview_uninit (); } } -/* We rely on some knowledge of how g_list_insert_sorted works to make - * sure that we insert after timeouts of equal interval - */ static gint -gtk_timeout_compare (gpointer a, gpointer b) +gtk_quit_invoke_function (GtkQuitFunction *quitf) { - return (((GtkTimeoutFunction *)a)->interval < - ((GtkTimeoutFunction *)b)->interval) - ? -1 : 1; -} - -static void -gtk_timeout_insert (GtkTimeoutFunction *timeoutf) -{ - g_assert (timeoutf != NULL); - - /* Insert the timeout function appropriately. - * Appropriately meaning sort it into the list - * of timeout functions. - */ - timeout_functions = g_list_insert_sorted (timeout_functions, timeoutf, - gtk_timeout_compare); -} - -static gint -gtk_invoke_timeout_function (GtkTimeoutFunction *timeoutf) -{ - if (!timeoutf->marshal) - return timeoutf->function (timeoutf->data); + if (!quitf->marshal) + return quitf->function (quitf->data); else { GtkArg args[1]; gint ret_val = FALSE; - args[0].name = NULL; - args[0].type = GTK_TYPE_BOOL; - args[0].d.pointer_data = &ret_val; - ((GtkCallbackMarshal)timeoutf->function) (NULL, - timeoutf->data, - 0, args); - return ret_val; - } -} -static void -gtk_handle_current_timeouts (guint32 the_time) -{ - GList *tmp_list; - GtkTimeoutFunction *timeoutf; - - while (current_timeouts) - { - tmp_list = current_timeouts; - timeoutf = tmp_list->data; - - current_timeouts = g_list_remove_link (current_timeouts, tmp_list); - g_list_free (tmp_list); - - if (gtk_invoke_timeout_function (timeoutf) == FALSE) - { - gtk_timeout_destroy (timeoutf); - } - else - { - timeoutf->interval = timeoutf->originterval; - timeoutf->start = the_time; - gtk_timeout_insert (timeoutf); - } - } -} - -static void -gtk_handle_timeouts () -{ - guint32 the_time; - GList *tmp_list; - GList *tmp_list2; - GtkTimeoutFunction *timeoutf; - - /* Caller must already have called gtk_handle_current_timeouts if - * necessary */ - g_assert (current_timeouts == NULL); - - if (timeout_functions) - { - the_time = gdk_time_get (); - - tmp_list = timeout_functions; - while (tmp_list) - { - timeoutf = tmp_list->data; - - if (timeoutf->interval <= (the_time - timeoutf->start)) - { - tmp_list2 = tmp_list; - tmp_list = tmp_list->next; - - timeout_functions = g_list_remove_link (timeout_functions, tmp_list2); - current_timeouts = g_list_concat (current_timeouts, tmp_list2); - } - else - { - timeoutf->interval -= (the_time - timeoutf->start); - timeoutf->start = the_time; - tmp_list = tmp_list->next; - } - } - - if (current_timeouts) - gtk_handle_current_timeouts(the_time); - } -} - -static gint -gtk_idle_invoke_function (GtkIdleFunction *idlef) -{ - if (!idlef->marshal) - return idlef->function (idlef->data); - else - { - GtkArg args[1]; - gint ret_val = FALSE; args[0].name = NULL; args[0].type = GTK_TYPE_BOOL; args[0].d.pointer_data = &ret_val; - ((GtkCallbackMarshal)idlef->marshal) (NULL, - idlef->data, - 0, args); + ((GtkCallbackMarshal) quitf->marshal) (NULL, + quitf->data, + 0, args); return ret_val; } } -static void -gtk_handle_current_idles () -{ - GList *tmp_list; - GList *tmp_list2; - GtkIdleFunction *idlef; - - while (current_idles) - { - tmp_list = current_idles; - idlef = tmp_list->data; - - current_idles = g_list_remove_link (current_idles, tmp_list); - - if (gtk_idle_invoke_function (idlef) == FALSE) - { - g_list_free (tmp_list); - gtk_idle_destroy (idlef); - } - else - { - /* Insert the idle function back into the list of idle - * functions at the end of the idles of this priority - */ - tmp_list2 = idle_functions; - while (tmp_list2 && - (((GtkIdleFunction *)tmp_list2->data)->priority <= idlef->priority)) - tmp_list2 = tmp_list2->next; - - if (!tmp_list2) - idle_functions = g_list_concat (idle_functions, tmp_list); - else if (tmp_list2 == idle_functions) - { - tmp_list->next = idle_functions; - if (idle_functions) - idle_functions->prev = tmp_list; - idle_functions = tmp_list; - } - else - { - tmp_list->prev = tmp_list2->prev; - tmp_list->next = tmp_list2; - tmp_list2->prev->next = tmp_list; - tmp_list2->prev = tmp_list; - } - } - } -} - -static void -gtk_handle_idle () -{ - /* Caller must already have called gtk_handle_current_idles if - * necessary - */ - g_assert (current_idles == NULL); - - /* Handle only the idle functions that have the highest priority */ - if (idle_functions) - { - GList *tmp_list; - gint top_priority; - - tmp_list = idle_functions; - top_priority = ((GtkIdleFunction *)tmp_list->data)->priority; - - while (tmp_list && - (((GtkIdleFunction *)tmp_list->data)->priority == top_priority)) - tmp_list = tmp_list->next; - - current_idles = idle_functions; - idle_functions = tmp_list; - - if (tmp_list) - { - tmp_list->prev->next = NULL; - tmp_list->prev = NULL; - } - - gtk_handle_current_idles(); - } -} - -static void -gtk_handle_timer () -{ - GtkTimeoutFunction *timeoutf; - - if (idle_functions) - { - gdk_timer_set (0); - gdk_timer_enable (); - } - else if (timeout_functions) - { - timeoutf = timeout_functions->data; - gdk_timer_set (timeoutf->interval); - gdk_timer_enable (); - } - else - { - gdk_timer_set (0); - gdk_timer_disable (); - } -} - -static void +void gtk_propagate_event (GtkWidget *widget, GdkEvent *event) { - GtkWidget *parent; - GtkWidget *tmp; gint handled_event; g_return_if_fail (widget != NULL); + g_return_if_fail (GTK_IS_WIDGET (widget)); g_return_if_fail (event != NULL); handled_event = FALSE; - gtk_widget_ref (widget); if ((event->type == GDK_KEY_PRESS) || (event->type == GDK_KEY_RELEASE)) { - - /* Only send key events to window widgets. - * The window widget will in turn pass the + /* Only send key events within Window widgets to the Window + * The Window widget will in turn pass the * key event on to the currently focused widget * for that window. */ - parent = gtk_widget_get_ancestor (widget, gtk_window_get_type ()); - handled_event = (parent && - GTK_WIDGET_IS_SENSITIVE (parent) && - gtk_widget_event (parent, event)); + GtkWidget *window; + + window = gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW); + if (window) + { + if (GTK_WIDGET_IS_SENSITIVE (window)) + gtk_widget_event (window, event); + + handled_event = TRUE; /* don't send to widget */ + } } /* Other events get propagated up the widget tree * so that parents can see the button and motion * events of the children. */ - tmp = widget; - while (!handled_event && tmp) + while (!handled_event && widget) { - gtk_widget_ref (tmp); - handled_event = !GTK_WIDGET_IS_SENSITIVE (tmp) || gtk_widget_event (tmp, event); - parent = tmp->parent; - gtk_widget_unref (tmp); - tmp = parent; - } + GtkWidget *tmp; - gtk_widget_unref (widget); + gtk_widget_ref (widget); + handled_event = !GTK_WIDGET_IS_SENSITIVE (widget) || gtk_widget_event (widget, event); + tmp = widget->parent; + gtk_widget_unref (widget); + widget = tmp; + } } - +#if 0 static void gtk_error (gchar *str) { @@ -1369,7 +1337,7 @@ gtk_print (gchar *str) box2 = gtk_vbox_new (FALSE, 10); - gtk_container_border_width (GTK_CONTAINER (box2), 10); + gtk_container_set_border_width (GTK_CONTAINER (box2), 10); gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0); gtk_widget_show (box2); @@ -1402,7 +1370,7 @@ gtk_print (gchar *str) box2 = gtk_vbox_new (FALSE, 10); - gtk_container_border_width (GTK_CONTAINER (box2), 10); + gtk_container_set_border_width (GTK_CONTAINER (box2), 10); gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0); gtk_widget_show (box2); @@ -1424,3 +1392,4 @@ gtk_print (gchar *str) if (!GTK_WIDGET_VISIBLE (window)) gtk_widget_show (window); } +#endif