* 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.
*/
+
+/*
+ * 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 "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_compare (gpointer a,
- gpointer b);
-
-static gint gtk_timeout_compare (gpointer a,
- gpointer b);
+#endif
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 *quit_functions = NULL; /* A list of quit 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 *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;
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}
+ {"misc", GTK_DEBUG_MISC},
+ {"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 *current_locale;
-
- if (0)
+ gchar *suffix = strrchr(module_name, '.');
+
+ if (!suffix || stricmp(suffix, ".dll"))
{
- g_set_error_handler (gtk_error);
- g_set_warning_handler (gtk_warning);
- g_set_message_handler (gtk_message);
- g_set_print_handler (gtk_print);
+ 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)
+{
+ extern void gtk_object_post_arg_parsing_init (void);
+ GSList *gtk_modules = NULL;
+ GSList *slist;
+ gchar *env_string = NULL;
+
+ if (gtk_initialized)
+ return TRUE;
+
+#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);
+ 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)
+ if (strcmp ("--gtk-module", (*argv)[i]) == 0 ||
+ strncmp ("--gtk-module=", (*argv)[i], 13) == 0)
{
+ 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 ((i + 1) < *argc && (*argv)[i + 1])
+ 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,
+ 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++)
}
}
}
-
-#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 were 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);
-
- GTK_NOTE(MISC, g_print("%s multi-byte string functions.\n",
- gtk_use_mb ? "Using" : "Not using"));
+#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
/* Initialize the default visual and colormap to be
* used in creating widgets. (We want to use the system
*/
gtk_visual = gdk_visual_get_system ();
gtk_colormap = gdk_colormap_get_system ();
+
+ gtk_type_init ();
+ gtk_object_post_arg_parsing_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);
+
+#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.
*/
}
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;
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)
{
quit_functions = g_list_remove_link (quit_functions, quit_functions);
- if ((quitf->main_level && quitf->main_level != main_level) ||
+ if ((quitf->main_level && quitf->main_level != gtk_main_loop_level) ||
gtk_quit_invoke_function (quitf))
{
reinvoke_list = g_list_prepend (reinvoke_list, quitf);
}
if (reinvoke_list)
{
- GList *tmp_list;
+ GList *work;
- tmp_list = g_list_last (reinvoke_list);
+ work = g_list_last (reinvoke_list);
if (quit_functions)
- quit_functions->prev = tmp_list;
- tmp_list->next = quit_functions;
- quit_functions = tmp_list;
+ quit_functions->prev = work;
+ work->next = quit_functions;
+ quit_functions = work;
}
+
+ gdk_flush ();
}
- main_level--;
+ 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)
{
- gint result = gdk_events_pending() + ((next_event != NULL) ? 1 : 0);
+ return g_main_pending();
+}
- if (idle_functions &&
- (((GtkIdleFunction *)idle_functions->data)->priority >=
- GTK_PRIORITY_INTERNAL))
- result += 1;
+gint
+gtk_main_iteration (void)
+{
+ g_main_iteration (TRUE);
- return result;
+ if (main_loops)
+ return !g_main_is_running (main_loops->data);
+ else
+ return TRUE;
}
gint
-gtk_main_iteration ()
+gtk_main_iteration_do (gboolean blocking)
{
- return gtk_main_iteration_do (TRUE);
+ g_main_iteration (blocking);
+
+ if (main_loops)
+ return !g_main_is_running (main_loops->data);
+ else
+ return TRUE;
}
-gint
-gtk_main_iteration_do (gboolean blocking)
+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().
+ */
+ current_events = g_list_prepend (current_events, event);
+
+ /* 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_PRIVATE_UNSET_FLAG (event_widget, GTK_LEAVE_PENDING);
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_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 ();
-
- return iteration_done;
+ tmp_list = current_events;
+ current_events = g_list_remove_link (current_events, tmp_list);
+ g_list_free_1 (tmp_list);
}
gint
}
guint
-gtk_timeout_add_full (guint32 interval,
- GtkFunction function,
- GtkCallbackMarshal marshal,
- gpointer data,
- GtkDestroyNotify destroy)
+gtk_quit_add_full (guint main_level,
+ GtkFunction function,
+ GtkCallbackMarshal marshal,
+ gpointer data,
+ GtkDestroyNotify destroy)
{
- static guint 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);
-
- timeoutf = g_chunk_new (GtkTimeoutFunction, timeout_mem_chunk);
+ if (!quit_mem_chunk)
+ quit_mem_chunk = g_mem_chunk_new ("quit mem chunk", sizeof (GtkQuitFunction),
+ 512, G_ALLOC_AND_FREE);
- 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 = g_chunk_new (GtkQuitFunction, quit_mem_chunk);
- gtk_timeout_insert (timeoutf);
+ 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);
- 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);
-}
-
-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);
-}
-
-void
-gtk_timeout_remove (guint tag)
-{
- GtkTimeoutFunction *timeoutf;
- GList *tmp_list;
-
- /* Remove a timeout function.
- * (Which, basically, involves searching the
- * list for the tag).
- */
- tmp_list = timeout_functions;
- while (tmp_list)
- {
- timeoutf = tmp_list->data;
-
- if (timeoutf->tag == tag)
- {
- timeout_functions = g_list_remove_link (timeout_functions, tmp_list);
- g_list_free (tmp_list);
- gtk_timeout_destroy (timeoutf);
-
- return;
- }
-
- tmp_list = tmp_list->next;
- }
-
- tmp_list = current_timeouts;
- while (tmp_list)
- {
- timeoutf = tmp_list->data;
-
- if (timeoutf->tag == tag)
- {
- current_timeouts = g_list_remove_link (current_timeouts, tmp_list);
- g_list_free (tmp_list);
- gtk_timeout_destroy (timeoutf);
-
- return;
- }
-
- tmp_list = tmp_list->next;
- }
-}
-
-/* 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)
-{
- return (((GtkIdleFunction *)a)->priority < ((GtkIdleFunction *)b)->priority)
- ? -1 : 1;
-}
-
-guint
-gtk_quit_add_full (guint main_level,
- GtkFunction function,
- GtkCallbackMarshal marshal,
- gpointer data,
- GtkDestroyNotify destroy)
-{
- static guint quit_id = 1;
- GtkQuitFunction *quitf;
-
- g_return_val_if_fail ((function != NULL) || (marshal != NULL), 0);
-
- if (!quit_mem_chunk)
- quit_mem_chunk = g_mem_chunk_new ("quit mem chunk", sizeof (GtkQuitFunction),
- 512, G_ALLOC_AND_FREE);
-
- quitf = g_chunk_new (GtkQuitFunction, quit_mem_chunk);
-
- 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);
-
- 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;
-
- 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)
-{
- if (quitf->destroy)
- quitf->destroy (quitf->data);
- g_mem_chunk_free (quit_mem_chunk, quitf);
+ if (quitf->destroy)
+ quitf->destroy (quitf->data);
+ g_mem_chunk_free (quit_mem_chunk, quitf);
}
static gint
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)
{
}
}
-void
-gtk_idle_remove (guint tag)
+guint
+gtk_timeout_add_full (guint32 interval,
+ GtkFunction function,
+ GtkCallbackMarshal marshal,
+ gpointer data,
+ GtkDestroyNotify destroy)
{
- 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)
+ if (marshal)
{
- 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;
+ 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);
+}
+
+guint
+gtk_timeout_add (guint32 interval,
+ GtkFunction function,
+ gpointer data)
+{
+ return g_timeout_add_full (0, interval, function, data, NULL);
}
void
-gtk_idle_remove_by_data (gpointer data)
+gtk_timeout_remove (guint tag)
{
- 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);
- gtk_idle_destroy (idlef);
-
- return;
- }
-
- tmp_list = tmp_list->next;
- }
-
- tmp_list = current_idles;
- while (tmp_list)
+ g_source_remove (tag);
+}
+
+guint
+gtk_idle_add_full (gint priority,
+ GtkFunction function,
+ GtkCallbackMarshal marshal,
+ gpointer data,
+ GtkDestroyNotify destroy)
+{
+ if (marshal)
{
- idlef = tmp_list->data;
-
- if (idlef->data == data)
- {
- 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;
+ 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);
}
-static void
-gtk_invoke_input_function (GtkInputFunction *input,
- gint source,
- GdkInputCondition condition)
+guint
+gtk_idle_add (GtkFunction function,
+ gpointer 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;
+ return g_idle_add_full (GTK_PRIORITY_DEFAULT, function, data, NULL);
+}
- input->callback (NULL, input->data, 2, args);
+guint
+gtk_idle_add_priority (gint priority,
+ GtkFunction function,
+ gpointer data)
+{
+ return g_idle_add_full (priority, function, data, NULL);
}
-static void
-gtk_destroy_input_function (GtkInputFunction *input)
+void
+gtk_idle_remove (guint tag)
{
- if (input->destroy)
- (input->destroy) (input->data);
- g_free (input);
+ 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);
}
-guint
-gtk_input_add_interp (gint source,
- GdkInputCondition condition,
- GtkCallbackMarshal callback,
- gpointer data,
- GtkDestroyNotify destroy)
-{
- return gtk_input_add_full (source, condition, NULL, callback, data, destroy);
-}
-
void
gtk_input_remove (guint tag)
{
- gdk_input_remove (tag);
+ g_source_remove (tag);
}
-GdkEvent *
-gtk_get_current_event ()
+static void
+gtk_destroy_closure (gpointer data)
{
- if (current_events)
- return gdk_event_copy ((GdkEvent *) current_events->data);
- else
- return NULL;
+ GtkClosure *closure = data;
+
+ if (closure->destroy)
+ (closure->destroy) (closure->data);
+ g_free (closure);
}
-GtkWidget*
-gtk_get_event_widget (GdkEvent *event)
+static gboolean
+gtk_invoke_idle_timeout (gpointer data)
{
- GtkWidget *widget;
+ GtkClosure *closure = data;
- widget = NULL;
- if (event->any.window)
- gdk_window_get_user_data (event->any.window, (void**) &widget);
-
- return widget;
+ 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_exit_func ()
+gtk_invoke_input (gpointer data,
+ gint source,
+ GdkInputCondition condition)
{
- if (initialized)
- {
- initialized = FALSE;
- gtk_preview_uninit ();
- }
-}
+ 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;
-/* 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)
-{
- 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);
+ closure->marshal (NULL, closure->data, 2, args);
}
-static gint
-gtk_invoke_timeout_function (GtkTimeoutFunction *timeoutf)
+GdkEvent*
+gtk_get_current_event (void)
{
- if (!timeoutf->marshal)
- return timeoutf->function (timeoutf->data);
+ if (current_events)
+ return gdk_event_copy ((GdkEvent *) current_events->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;
- }
+ return NULL;
}
-static void
-gtk_handle_current_timeouts (guint32 the_time)
+GtkWidget*
+gtk_get_event_widget (GdkEvent *event)
{
- GList *tmp_list;
- GtkTimeoutFunction *timeoutf;
+ GtkWidget *widget;
+
+ widget = NULL;
+ if (event && event->any.window)
+ gdk_window_get_user_data (event->any.window, (void**) &widget);
- 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);
- }
- }
+ return widget;
}
static void
-gtk_handle_timeouts ()
+gtk_exit_func (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)
+ if (gtk_initialized)
{
- 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);
+ gtk_initialized = FALSE;
+ gtk_preview_uninit ();
}
}
+
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 ()
-{
- 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)
{
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