* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
+
+/*
+ * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
+ * file for a list of people on the GTK+ Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#include "gdkx.h" /* For GDK_WINDOWING */
+
+#ifdef GDK_WINDOWING_X11
#include <X11/Xlocale.h> /* so we get the right setlocale */
+#else
+#include <locale.h>
+#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gmodule.h>
#include "gtkbutton.h"
-#include "gtkfeatures.h"
+#include "gtkdnd.h"
+#include "gtkcompat.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"
#include "gtkwindow.h"
#include "gtkprivate.h"
#include "gdk/gdki18n.h"
-#include "../config.h"
+#include "config.h"
#include "gtkdebug.h"
-
+#include "gtkintl.h"
/* Private type definitions
*/
typedef struct _GtkInitFunction GtkInitFunction;
typedef struct _GtkQuitFunction GtkQuitFunction;
-typedef struct _GtkTimeoutFunction GtkTimeoutFunction;
-typedef struct _GtkIdleFunction GtkIdleFunction;
-typedef struct _GtkInputFunction GtkInputFunction;
+typedef struct _GtkClosure GtkClosure;
typedef struct _GtkKeySnooperData GtkKeySnooperData;
struct _GtkInitFunction
GtkDestroyNotify destroy;
};
-struct _GtkTimeoutFunction
-{
- guint tag;
- guint32 start;
- guint32 interval;
- guint32 originterval;
- GtkFunction function;
- GtkCallbackMarshal marshal;
- gpointer data;
- GtkDestroyNotify destroy;
-};
-
-struct _GtkIdleFunction
+struct _GtkClosure
{
- guint tag;
- gint priority;
GtkCallbackMarshal marshal;
- GtkFunction function;
- gpointer data;
- GtkDestroyNotify destroy;
-};
-
-struct _GtkInputFunction
-{
- GtkCallbackMarshal callback;
gpointer data;
GtkDestroyNotify destroy;
};
static void gtk_exit_func (void);
static gint gtk_quit_invoke_function (GtkQuitFunction *quitf);
static void gtk_quit_destroy (GtkQuitFunction *quitf);
-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,
- 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);
-
-static gint gtk_idle_remove_from_list (GList **list,
- guint tag,
- gpointer data,
- gint remove_link);
-static gint gtk_timeout_remove_from_list (GList **list,
- guint tag,
- gint remove_link);
-
-static gint gtk_idle_compare (gconstpointer a,
- gconstpointer b);
-
-static gint gtk_timeout_compare (gconstpointer a,
- gconstpointer b);
+#endif
const guint gtk_major_version = GTK_MAJOR_VERSION;
const guint gtk_minor_version = GTK_MINOR_VERSION;
const guint gtk_binary_age = GTK_BINARY_AGE;
const guint gtk_interface_age = GTK_INTERFACE_AGE;
-static gboolean iteration_done = FALSE;
static guint gtk_main_loop_level = 0;
static gint gtk_initialized = FALSE;
-static GdkEvent *next_event = NULL;
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 *quit_functions = NULL; /* A list of quit functions.
*/
-
-
-/* When handling timeouts, the algorithm is to move all of the expired
- * timeouts from timeout_functions to current_timeouts then process
- * them as a batch. If one of the timeouts recursively calls the main
- * loop, then the remainder of the timeouts in current_timeouts will
- * be processed before anything else happens.
- *
- * Each timeout is procesed as follows:
- *
- * - The timeout is removed from current_timeouts
- * - The timeout is pushed on the running_timeouts stack
- * - The timeout is executed
- * - The timeout stack is popped
- * - If the timeout function wasn't removed from the stack while executing,
- * and it returned TRUE, it is added back to timeout_functions, otherwise
- * it is destroyed if necessary.
- *
- * gtk_timeout_remove() works by checking for the timeout in
- * timeout_functions current_timeouts and running_timeouts. If it is
- * found in one of the first two, it is removed and destroyed. If it
- * is found in running_timeouts, it is destroyed and ->data is set to
- * NULL for the stack entry.
- *
- * Idle functions work pretty much identically.
- */
-
-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.
- */
-
-/* The idle functions / timeouts that are currently being processed
- * by gtk_handle_current_(timeouts/idles)
- */
-static GList *current_idles = NULL;
-static GList *current_timeouts = NULL;
-
-/* A stack of idle functions / timeouts that are currently being
- * being executed
- */
-static GList *running_idles = NULL;
-static GList *running_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;
guint gtk_debug_flags = 0; /* Global GTK debug flag */
#ifdef G_ENABLE_DEBUG
-static GDebugKey gtk_debug_keys[] = {
+static const GDebugKey gtk_debug_keys[] = {
{"objects", GTK_DEBUG_OBJECTS},
{"misc", GTK_DEBUG_MISC},
- {"signals", GTK_DEBUG_SIGNALS}
+ {"signals", GTK_DEBUG_SIGNALS},
+ {"dnd", GTK_DEBUG_DND},
+ {"plugsocket", GTK_DEBUG_PLUGSOCKET}
};
static const guint gtk_ndebug_keys = sizeof (gtk_debug_keys) / sizeof (GDebugKey);
#endif /* G_ENABLE_DEBUG */
-gint gtk_use_mb = -1;
+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)
+#ifdef __EMX__
+static gchar *add_dll_suffix(gchar *module_name)
+{
+ gchar *suffix = strrchr(module_name, '.');
+
+ if (!suffix || stricmp(suffix, ".dll"))
+ {
+ gchar *old = module_name;
+
+ module_name = g_strconcat (module_name, ".dll", NULL);
+ g_free (old);
+ }
+ return (module_name);
+}
+#endif
+
+gboolean
+gtk_init_check (int *argc,
+ char ***argv)
{
- GSList *gtk_modinit_funcs = NULL;
- gchar *current_locale;
+ extern void gtk_object_post_arg_parsing_init (void);
+ GSList *gtk_modules = NULL;
+ GSList *slist;
+ gchar *env_string = NULL;
if (gtk_initialized)
- return;
+ return TRUE;
#if 0
g_set_error_handler (gtk_error);
/* Initialize "gdk". We pass along the 'argc' and 'argv'
* parameters as they contain information that GDK uses
*/
- gdk_init (argc, argv);
+ if (!gdk_init_check (argc, argv))
+ return FALSE;
+
+ 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;
+
+#ifndef __EMX__
+ modules = g_strsplit (env_string, G_SEARCHPATH_SEPARATOR_S, -1);
+#else
+ modules = g_strsplit (env_string, ";", -1);
+#endif
+ 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)
{
for (i = 1; i < *argc;)
{
- if ((strcmp ("--gtk-debug", (*argv)[i]) == 0) ||
- (strncmp ("--gtk-debug=", (*argv)[i], 12) == 0))
+ if (strcmp ("--gtk-module", (*argv)[i]) == 0 ||
+ strncmp ("--gtk-module=", (*argv)[i], 13) == 0)
{
- gchar *equal_pos = strchr ((*argv)[i], '=');
+ gchar *module_name = (*argv)[i] + 12;
+
+ if (*module_name == '=')
+ module_name++;
+ else
+ {
+ (*argv)[i] = NULL;
+ i += 1;
+ module_name = (*argv)[i];
+ }
+ (*argv)[i] = NULL;
+ 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;
+ }
+#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,
(strncmp ("--gtk-no-debug=", (*argv)[i], 15) == 0))
{
gchar *equal_pos = strchr ((*argv)[i], '=');
-
+
if (equal_pos != NULL)
{
gtk_debug_flags &= ~g_parse_debug_string (equal_pos+1,
}
(*argv)[i] = NULL;
}
- else if (strcmp ("--gtk-module", (*argv)[i]) == 0 ||
- strncmp ("--gtk-module=", (*argv)[i], 13) == 0)
- {
- GModule *module = NULL;
- GtkModuleInitFunc modinit_func = NULL;
- gchar *module_name = (*argv)[i] + 12;
-
- if (*module_name == '=')
- module_name++;
- else
- {
- (*argv)[i] = NULL;
- i += 1;
- module_name = (*argv)[i];
- }
- if (module_name[0] == '/' ||
- (module_name[0] == 'l' &&
- module_name[1] == 'i' &&
- module_name[2] == 'b'))
- module_name = g_strdup (module_name);
- else
- module_name = g_strconcat ("lib", module_name, ".so", NULL);
- (*argv)[i] = NULL;
-
- 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_modinit_funcs, modinit_func))
- gtk_modinit_funcs = g_slist_prepend (gtk_modinit_funcs, 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);
- }
- 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;
- }
+#endif /* G_ENABLE_DEBUG */
i += 1;
}
-
+
for (i = 1; i < *argc; i++)
{
for (k = i; k < *argc; k++)
}
}
}
-
-#endif /* G_ENABLE_DEBUG */
-
- /* Check if there is a good chance the mb functions will handle things
- * correctly - set if either mblen("\xc0", MB_CUR_MAX) == 1 in the
- * C locale, or we're using X's mb functions. (-DX_LOCALE && locale != C)
- */
-
- current_locale = g_strdup (setlocale (LC_CTYPE, NULL));
-
-#ifdef X_LOCALE
- if ((strcmp (current_locale, "C")) && (strcmp (current_locale, "POSIX")))
- gtk_use_mb = TRUE;
- else
-#endif
+
+ /* load gtk modules */
+ gtk_modules = g_slist_reverse (gtk_modules);
+ for (slist = gtk_modules; slist; slist = slist->next)
{
- setlocale (LC_CTYPE, "C");
- gtk_use_mb = (mblen ("\xc0", MB_CUR_MAX) == 1);
- setlocale (LC_CTYPE, current_locale);
+ gchar *module_name;
+ GModule *module = NULL;
+ GtkModuleInitFunc modinit_func = NULL;
+
+ module_name = slist->data;
+ slist->data = NULL;
+#ifndef __EMX__
+ if (!g_path_is_absolute (module_name))
+ {
+ gchar *old = module_name;
+
+ module_name = g_module_build_path (NULL, module_name);
+ g_free (old);
+ }
+#else
+ module_name = add_dll_suffix(module_name);
+#endif
+ 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);
}
- g_free (current_locale);
+#ifdef ENABLE_NLS
+#ifndef G_OS_WIN32
+ bindtextdomain("gtk+", GTK_LOCALEDIR);
+#else
+ {
+ /* GTk+ locale dir is %WinDir%\gtk+\locale */
+ extern char *get_gtk_sysconf_directory ();
+ bindtextdomain ("gtk+", g_strconcat (get_gtk_sysconf_directory (),
+ G_DIR_SEPARATOR_S,
+ "locale",
+ NULL));
+ }
+#endif
+#endif
- GTK_NOTE (MISC,
- g_message ("%s multi-byte string functions.\n",
- gtk_use_mb ? "Using" : "Not using"));
-
/* Initialize the default visual and colormap to be
* used in creating widgets. (We want to use the system
* defaults so as to be nice to the colormap).
gtk_colormap = gdk_colormap_get_system ();
gtk_type_init ();
+ gtk_object_post_arg_parsing_init ();
gtk_signal_init ();
gtk_rc_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.
*/
gtk_initialized = TRUE;
- /* initialize modules
+ /* initialize gtk modules
*/
- if (gtk_modinit_funcs)
+ for (slist = gtk_modules; slist; slist = slist->next)
{
- GSList *slist;
-
- slist = gtk_modinit_funcs;
- while (slist)
+ if (slist->data)
{
GtkModuleInitFunc modinit;
-
+
modinit = slist->data;
modinit (argc, argv);
- slist = slist->next;
}
-
- g_slist_free (gtk_modinit_funcs);
+ }
+ g_slist_free (gtk_modules);
+
+#ifndef G_OS_WIN32
+ /* No use warning on Win32, there aren't any non-devel versions anyhow... */
+ g_warning ("" "YOU ARE USING THE DEVEL BRANCH 1.3.x OF GTK+ WHICH IS CURRENTLY\n"
+ " UNDER HEAVY DEVELOPMENT AND FREQUENTLY INTRODUCES INSTABILITIES.\n"
+ " if you don't know why you are getting this, you probably want to\n"
+ " use the stable branch which can be retrived from\n"
+ " ftp://ftp.gtk.org/pub/gtk/v1.2/ or via CVS with\n"
+ " cvs checkout -r glib-1-2 glib; cvs checkout -r gtk-1-2 gtk+");
+#endif
+
+ return TRUE;
+}
+void
+gtk_init (int *argc, char ***argv)
+{
+ if (!gtk_init_check (argc, argv))
+ {
+ g_warning ("cannot open display: %s", gdk_get_display ());
+ exit(1);
}
}
void
-gtk_exit (int errorcode)
+gtk_exit (gint errorcode)
{
/* Only if "gtk" has been initialized should we de-initialize.
*/
GList *tmp_list;
GList *functions;
GtkInitFunction *init;
- int old_done;
-
+ 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;
g_free (init);
}
g_list_free (functions);
-
- old_done = iteration_done;
- while (!gtk_main_iteration ())
- ;
- iteration_done = old_done;
+
+ if (g_main_is_running (main_loops->data))
+ {
+ GDK_THREADS_LEAVE ();
+ g_main_run (loop);
+ GDK_THREADS_ENTER ();
+ gdk_flush ();
+ }
if (quit_functions)
{
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--;
}
void
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)
{
- gint result = 0;
-
- /* if this function is called from a timeout which will only return
- * if gtk needs processor time, we need to take iteration_done==TRUE
- * into account as well.
- */
- result = iteration_done;
- result += next_event != NULL;
- result += gdk_events_pending();
-
- result += current_idles != NULL;
- result += current_timeouts != NULL;
-
- if (!result)
- {
- result += (idle_functions &&
- (((GtkIdleFunction *)idle_functions->data)->priority <=
- GTK_PRIORITY_INTERNAL));
- }
-
- if (!result && timeout_functions)
- {
- guint32 the_time;
- GtkTimeoutFunction *timeoutf;
-
- the_time = gdk_time_get ();
-
- timeoutf = timeout_functions->data;
-
- result += timeoutf->interval <= (the_time - timeoutf->start);
- }
-
- return result;
+ return g_main_pending();
}
gint
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;
+
+ /* If there are any events pending then get the next one.
+ */
+ next_event = gdk_event_peek ();
- 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()
+ /* 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 (current_timeouts)
- {
- gtk_handle_current_timeouts( gdk_time_get());
-
- if (iteration_done)
- gdk_flush ();
+ 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;
+ }
- return iteration_done;
- }
- if (current_idles)
+ 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)
{
- gtk_handle_current_idles ();
-
- if (iteration_done)
- gdk_flush ();
-
- return iteration_done;
+ /* 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 there is a valid event in 'next_event' then move it to 'event'
+ /* Push the event onto a stack of current events for
+ * gtk_current_event_get().
*/
- if (next_event)
- {
- event = next_event;
- next_event = NULL;
- }
+ current_events = g_list_prepend (current_events, event);
- /* If we don't have an event then get one.
+ /* If there is a grab in effect...
*/
- if (!event)
+ 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_SENSITIVE (event_widget) &&
- 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_OBJECT_DESTROYED (event_widget))
- 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);
- 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_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);
+ 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;
}
- else
- {
- if (gdk_events_pending() == 0)
- gtk_handle_idle ();
- }
-
-event_handling_done:
-
- /* Handle timeout functions that may have expired.
- */
- gtk_handle_timeouts ();
-
- if (iteration_done)
- gdk_flush ();
- return iteration_done;
+ tmp_list = current_events;
+ current_events = g_list_remove_link (current_events, tmp_list);
+ g_list_free_1 (tmp_list);
}
gint
return return_val;
}
-guint
-gtk_timeout_add_full (guint32 interval,
- GtkFunction function,
- GtkCallbackMarshal marshal,
- gpointer data,
- GtkDestroyNotify destroy)
-{
- static guint timeout_tag = 1;
- GtkTimeoutFunction *timeoutf;
-
- 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);
-
- timeoutf = g_chunk_new (GtkTimeoutFunction, timeout_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;
-
- gtk_timeout_insert (timeoutf);
-
- return timeoutf->tag;
-}
-
-static void
-gtk_timeout_destroy (GtkTimeoutFunction *timeoutf)
-{
- if (timeoutf->destroy)
- (timeoutf->destroy) (timeoutf->data);
- g_mem_chunk_free (timeout_mem_chunk, timeoutf);
-}
-
-guint
-gtk_timeout_add (guint32 interval,
- GtkFunction function,
- gpointer data)
-{
- return gtk_timeout_add_full (interval, function, FALSE, data, NULL);
-}
-
-guint
-gtk_timeout_add_interp (guint32 interval,
- GtkCallbackMarshal function,
- gpointer data,
- GtkDestroyNotify destroy)
-{
- return gtk_timeout_add_full (interval, NULL, function, data, destroy);
-}
-
-/* Search for the specified tag in a list of timeouts. If it
- * is found, destroy the timeout, and either remove the link
- * or set link->data to NULL depending on remove_link
- */
-static gint
-gtk_timeout_remove_from_list (GList **list, guint tag, gint remove_link)
-{
- GList *tmp_list;
- GtkTimeoutFunction *timeoutf;
-
- tmp_list = *list;
- while (tmp_list)
- {
- timeoutf = tmp_list->data;
-
- if (timeoutf->tag == tag)
- {
- if (remove_link)
- {
- *list = g_list_remove_link (*list, tmp_list);
- g_list_free (tmp_list);
- }
- else
- tmp_list->data = NULL;
-
- gtk_timeout_destroy (timeoutf);
-
- return TRUE;
- }
-
- tmp_list = tmp_list->next;
- }
- return FALSE;
-}
-
-void
-gtk_timeout_remove (guint tag)
-{
-
- /* Remove a timeout function.
- * (Which, basically, involves searching the
- * list for the tag).
- */
-
- if (gtk_timeout_remove_from_list (&timeout_functions, tag, TRUE))
- return;
- if (gtk_timeout_remove_from_list (¤t_timeouts, tag, TRUE))
- return;
- if (gtk_timeout_remove_from_list (&running_timeouts, tag, FALSE))
- return;
-}
-
-/* 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 (gconstpointer a, gconstpointer b)
-{
- return (((const GtkIdleFunction *)a)->priority <
- ((const GtkIdleFunction *)b)->priority)
- ? -1 : 1;
-}
-
guint
gtk_quit_add_full (guint main_level,
GtkFunction function,
return quitf->id;
}
-guint
-gtk_idle_add_full (gint priority,
- GtkFunction function,
- GtkCallbackMarshal marshal,
- gpointer data,
- GtkDestroyNotify destroy)
-{
- static guint 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;
-
- /* If we are adding the first idle function, possibly wake up
- * the main thread out of its select().
- */
- if (!idle_functions)
- gdk_threads_wake ();
-
- idle_functions = g_list_insert_sorted (idle_functions, idlef, gtk_idle_compare);
-
-
- return idlef->tag;
-}
-
-guint
-gtk_idle_add_interp (GtkCallbackMarshal marshal,
- gpointer data,
- GtkDestroyNotify destroy)
-{
- return gtk_idle_add_full (GTK_PRIORITY_DEFAULT, NULL, marshal, data, destroy);
-}
-
-static void
-gtk_idle_destroy (GtkIdleFunction *idlef)
-{
- if (idlef->destroy)
- idlef->destroy (idlef->data);
- g_mem_chunk_free (idle_mem_chunk, idlef);
-}
-
static void
gtk_quit_destroy (GtkQuitFunction *quitf)
{
return gtk_quit_add_full (main_level, function, NULL, data, NULL);
}
-guint
-gtk_idle_add (GtkFunction function,
- gpointer data)
-{
- return gtk_idle_add_full (GTK_PRIORITY_DEFAULT, function, NULL, data, NULL);
-}
-
-guint
-gtk_idle_add_priority (gint priority,
- GtkFunction function,
- gpointer data)
-{
- return gtk_idle_add_full (priority, function, NULL, data, NULL);
-}
-
void
gtk_quit_remove (guint id)
{
}
}
-/* Search for the specified tag in a list of idles. If it
- * is found, destroy the idle, and either remove the link
- * or set link->data to NULL depending on remove_link
- *
- * If tag != 0, match tag against idlef->tag, otherwise, match
- * data against idlef->data
- */
-static gint
-gtk_idle_remove_from_list (GList **list,
- guint tag,
- gpointer data,
- gint remove_link)
+guint
+gtk_timeout_add_full (guint32 interval,
+ GtkFunction function,
+ GtkCallbackMarshal marshal,
+ gpointer data,
+ GtkDestroyNotify destroy)
{
- GtkIdleFunction *idlef;
- GList *tmp_list;
-
- tmp_list = *list;
- while (tmp_list)
+ if (marshal)
{
- idlef = tmp_list->data;
-
- if (((tag != 0) && (idlef->tag == tag)) ||
- ((tag == 0) && (idlef->data == data)))
- {
- if (remove_link)
- {
- *list = g_list_remove_link (*list, tmp_list);
- g_list_free (tmp_list);
- }
- else
- tmp_list->data = NULL;
+ GtkClosure *closure;
- gtk_idle_destroy (idlef);
-
- return TRUE;
- }
-
- tmp_list = tmp_list->next;
+ 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);
}
- return FALSE;
+ else
+ return g_timeout_add_full (0, interval, function, data, destroy);
}
-void
-gtk_idle_remove (guint tag)
+guint
+gtk_timeout_add (guint32 interval,
+ GtkFunction function,
+ gpointer data)
{
- g_return_if_fail (tag != 0);
-
- if (gtk_idle_remove_from_list (&idle_functions, tag, NULL, TRUE))
- return;
- if (gtk_idle_remove_from_list (¤t_idles, tag, NULL, TRUE))
- return;
- if (gtk_idle_remove_from_list (&running_idles, tag, NULL, FALSE))
- return;
+ return g_timeout_add_full (0, interval, function, data, NULL);
}
void
-gtk_idle_remove_by_data (gpointer data)
+gtk_timeout_remove (guint tag)
{
- if (gtk_idle_remove_from_list (&idle_functions, 0, data, TRUE))
- return;
- if (gtk_idle_remove_from_list (¤t_idles, 0, data, TRUE))
- return;
- if (gtk_idle_remove_from_list (&running_idles, 0, data, FALSE))
- return;
+ g_source_remove (tag);
}
-static void
-gtk_invoke_input_function (GtkInputFunction *input,
- gint source,
- GdkInputCondition condition)
+guint
+gtk_idle_add_full (gint priority,
+ GtkFunction function,
+ GtkCallbackMarshal marshal,
+ gpointer data,
+ GtkDestroyNotify destroy)
{
- 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;
+ if (marshal)
+ {
+ GtkClosure *closure;
- input->callback (NULL, input->data, 2, args);
+ 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);
}
-static void
-gtk_destroy_input_function (GtkInputFunction *input)
+guint
+gtk_idle_add (GtkFunction function,
+ gpointer data)
+{
+ return g_idle_add_full (GTK_PRIORITY_DEFAULT, function, data, NULL);
+}
+
+guint
+gtk_idle_add_priority (gint priority,
+ GtkFunction function,
+ gpointer data)
{
- if (input->destroy)
- (input->destroy) (input->data);
- g_free (input);
+ return g_idle_add_full (priority, function, data, NULL);
+}
+
+void
+gtk_idle_remove (guint tag)
+{
+ g_source_remove (tag);
+}
+
+void
+gtk_idle_remove_by_data (gpointer data)
+{
+ if (!g_idle_remove_by_data (data))
+ g_warning ("gtk_idle_remove_by_data(%p): no such idle", data);
}
guint
-gtk_input_add_full (gint source,
- GdkInputCondition condition,
- GdkInputFunction function,
- GtkCallbackMarshal marshal,
- gpointer data,
- GtkDestroyNotify destroy)
+gtk_input_add_full (gint source,
+ GdkInputCondition condition,
+ GdkInputFunction function,
+ GtkCallbackMarshal marshal,
+ gpointer data,
+ GtkDestroyNotify destroy)
{
if (marshal)
{
- GtkInputFunction *input;
+ GtkClosure *closure;
- input = g_new (GtkInputFunction, 1);
- input->callback = marshal;
- input->data = data;
- input->destroy = destroy;
+ 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);
void
gtk_input_remove (guint tag)
{
- gdk_input_remove (tag);
+ g_source_remove (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)
+{
+ 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;
}
-GdkEvent *
+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 (void)
{
if (current_events)
}
-/* 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 (gconstpointer a, gconstpointer b)
-{
- return (((const GtkTimeoutFunction *)a)->interval <
- ((const 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);
- 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;
- timeoutf->marshal (NULL, timeoutf->data, 0, args);
- return ret_val;
- }
-}
-
-static void
-gtk_handle_current_timeouts (guint32 the_time)
-{
- gint result;
- 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);
- if (running_timeouts)
- {
- running_timeouts->prev = tmp_list;
- tmp_list->next = running_timeouts;
- }
- running_timeouts = tmp_list;
-
- result = gtk_invoke_timeout_function (timeoutf);
-
- running_timeouts = g_list_remove_link (running_timeouts, tmp_list);
- timeoutf = tmp_list->data;
-
- g_list_free_1 (tmp_list);
-
- if (timeoutf)
- {
- if (!result)
- {
- gtk_timeout_destroy (timeoutf);
- }
- else
- {
- timeoutf->interval = timeoutf->originterval;
- timeoutf->start = the_time;
- gtk_timeout_insert (timeoutf);
- }
- }
- }
-}
-
-static void
-gtk_handle_timeouts (void)
-{
- 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_quit_invoke_function (GtkQuitFunction *quitf)
{
}
}
-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);
- return ret_val;
- }
-}
-
-static void
-gtk_handle_current_idles (void)
-{
- GList *tmp_list;
- GList *tmp_list2;
- GtkIdleFunction *idlef;
- gint result;
-
- while (current_idles)
- {
- tmp_list = current_idles;
- idlef = tmp_list->data;
-
- current_idles = g_list_remove_link (current_idles, tmp_list);
- if (running_idles)
- {
- running_idles->prev = tmp_list;
- tmp_list->next = running_idles;
- }
- running_idles = tmp_list;
-
- result = gtk_idle_invoke_function (idlef);
-
- running_idles = g_list_remove_link (running_idles, tmp_list);
- idlef = tmp_list->data;
-
- if (!idlef || !result)
- {
- g_list_free (tmp_list);
- if (idlef)
- 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 (void)
-{
- /* 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 (void)
-{
- 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)
{
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;
*/
GtkWidget *window;
- window = gtk_widget_get_ancestor (widget, gtk_window_get_type ());
+ window = gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW);
if (window)
{
if (GTK_WIDGET_IS_SENSITIVE (window))
}
}
-
+#if 0
static void
gtk_error (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);
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);
if (!GTK_WIDGET_VISIBLE (window))
gtk_widget_show (window);
}
-
+#endif