#include "config.h"
+#include "gtkmain.h"
+
#include <glib.h>
-#include "gdkconfig.h"
+#include "gdk/gdk.h"
#include <locale.h>
#include "gtkclipboard.h"
#include "gtkdnd.h"
#include "gtkversion.h"
-#include "gtkmain.h"
#include "gtkmodules.h"
#include "gtkrc.h"
#include "gtkrecentmanager.h"
#include "gtkselection.h"
#include "gtksettings.h"
-#include "gtkwidget.h"
-#include "gtkwindow.h"
+#include "gtkwidgetprivate.h"
+#include "gtkwindowprivate.h"
#include "gtktooltip.h"
#include "gtkdebug.h"
-#include "gtkalias.h"
#include "gtkmenu.h"
-#include "gdk/gdkkeysyms.h"
-
-#include "gdk/gdkprivate.h" /* for GDK_WINDOW_DESTROYED */
#ifdef G_OS_WIN32
/* Private type definitions
*/
-typedef struct _GtkInitFunction GtkInitFunction;
typedef struct _GtkQuitFunction GtkQuitFunction;
-typedef struct _GtkClosure GtkClosure;
typedef struct _GtkKeySnooperData GtkKeySnooperData;
-struct _GtkInitFunction
-{
- GtkFunction function;
- gpointer data;
-};
-
struct _GtkQuitFunction
{
guint id;
GDestroyNotify destroy;
};
-struct _GtkClosure
-{
- GtkCallbackMarshal marshal;
- gpointer data;
- GDestroyNotify destroy;
-};
-
struct _GtkKeySnooperData
{
GtkKeySnoopFunc func;
static gint gtk_invoke_key_snoopers (GtkWidget *grab_widget,
GdkEvent *event);
-static void gtk_destroy_closure (gpointer data);
-static gboolean gtk_invoke_idle_timeout (gpointer data);
-static void gtk_invoke_input (gpointer data,
- gint source,
- GdkInputCondition condition);
-
-#if 0
-static void gtk_error (gchar *str);
-static void gtk_warning (gchar *str);
-static void gtk_message (gchar *str);
-static void gtk_print (gchar *str);
-#endif
-
static GtkWindowGroup *gtk_main_get_window_group (GtkWidget *widget);
-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 guint gtk_main_loop_level = 0;
static gint pre_initialized = FALSE;
static gint gtk_initialized = FALSE;
static GSList *main_loops = NULL; /* stack of currently executing main loops */
-static GList *init_functions = NULL; /* A list of init functions.
- */
static GList *quit_functions = NULL; /* A list of quit functions.
*/
static GSList *key_snoopers = NULL;
-guint gtk_debug_flags = 0; /* Global GTK debug flag */
+static guint debug_flags = 0; /* Global GTK debug flag */
#ifdef G_ENABLE_DEBUG
static const GDebugKey gtk_debug_keys[] = {
{"geometry", GTK_DEBUG_GEOMETRY},
{"icontheme", GTK_DEBUG_ICONTHEME},
{"printing", GTK_DEBUG_PRINTING},
- {"builder", GTK_DEBUG_BUILDER}
+ {"builder", GTK_DEBUG_BUILDER},
+ {"size-request", GTK_DEBUG_SIZE_REQUEST},
};
#endif /* G_ENABLE_DEBUG */
+/**
+ * gtk_get_major_version:
+ *
+ * Returns the major version number of the GTK+ library. (e.g. in GTK+ version
+ * 3.1.5 this is 3.)
+ *
+ * This function is in the library, so it represents the GTK+ library
+ * your code is running against. Contrast with the #GTK_MAJOR_VERSION
+ * macro, which represents the major version of the GTK+ headers you
+ * have included when compiling your code.
+ *
+ * Returns: the major version number of the GTK+ library.
+ *
+ * Since: 3.0
+ */
+guint
+gtk_get_major_version (void)
+{
+ return GTK_MAJOR_VERSION;
+}
+
+/**
+ * gtk_get_minor_version:
+ *
+ * Returns the minor version number of the GTK+ library. (e.g. in GTK+ version
+ * 3.1.5 this is 1.)
+ *
+ * This function is in the library, so it represents the GTK+ library
+ * your code is are running against. Contrast with the
+ * #GTK_MINOR_VERSION macro, which represents the minor version of the
+ * GTK+ headers you have included when compiling your code.
+ *
+ * Returns: the minor version number of the GTK+ library.
+ *
+ * Since: 3.0
+ */
+guint
+gtk_get_minor_version (void)
+{
+ return GTK_MINOR_VERSION;
+}
+
+/**
+ * gtk_get_micro_version:
+ *
+ * Returns the micro version number of the GTK+ library. (e.g. in GTK+ version
+ * 3.1.5 this is 5.)
+ *
+ * This function is in the library, so it represents the GTK+ library
+ * your code is are running against. Contrast with the
+ * #GTK_MICRO_VERSION macro, which represents the micro version of the
+ * GTK+ headers you have included when compiling your code.
+ *
+ * Returns: the micro version number of the GTK+ library.
+ *
+ * Since: 3.0
+ */
+guint
+gtk_get_micro_version (void)
+{
+ return GTK_MICRO_VERSION;
+}
+
+/**
+ * gtk_get_binary_age:
+ *
+ * Returns the binary age as passed to
+ * <application>libtool</application> when building the GTK+ library
+ * the process is running against. If
+ * <application>libtool</application> means nothing to you, don't
+ * worry about it.
+ *
+ * Returns: the binary age of the GTK+ library.
+ *
+ * Since: 3.0
+ */
+guint
+gtk_get_binary_age (void)
+{
+ return GTK_BINARY_AGE;
+}
+
+/**
+ * gtk_get_interface_age:
+ *
+ * Returns the interface age as passed to
+ * <application>libtool</application> when building the GTK+ library
+ * the process is running against. If
+ * <application>libtool</application> means nothing to you, don't
+ * worry about it.
+ *
+ * Returns: the interface age of the GTK+ library.
+ *
+ * Since: 3.0
+ */
+guint
+gtk_get_interface_age (void)
+{
+ return GTK_INTERFACE_AGE;
+}
+
/**
* gtk_check_version:
* @required_major: the required major version.
* This function is primarily for GTK+ modules; the module
* can call this function to check that it wasn't loaded
* into an incompatible version of GTK+. However, such a
- * a check isn't completely reliable, since the module may be
+ * check isn't completely reliable, since the module may be
* linked against an old version of GTK+ and calling the
* old version of gtk_check_version(), but still get loaded
* into an application using a newer version of GTK+.
static gboolean
gtk_arg_debug_cb (const char *key, const char *value, gpointer user_data)
{
- gtk_debug_flags |= g_parse_debug_string (value,
- gtk_debug_keys,
- G_N_ELEMENTS (gtk_debug_keys));
+ debug_flags |= g_parse_debug_string (value,
+ gtk_debug_keys,
+ G_N_ELEMENTS (gtk_debug_keys));
return TRUE;
}
static gboolean
gtk_arg_no_debug_cb (const char *key, const char *value, gpointer user_data)
{
- gtk_debug_flags &= ~g_parse_debug_string (value,
- gtk_debug_keys,
- G_N_ELEMENTS (gtk_debug_keys));
+ debug_flags &= ~g_parse_debug_string (value,
+ gtk_debug_keys,
+ G_N_ELEMENTS (gtk_debug_keys));
return TRUE;
}
}
}
+static void
+check_mixed_deps (void)
+{
+ GModule *module;
+ gpointer func;
+
+ module = g_module_open (NULL, 0);
+
+ if (g_module_symbol (module, "gtk_progress_get_type", &func))
+ {
+ g_error ("GTK+ 2.x symbols detected. Using GTK+ 2.x and GTK+ 3 in the same process is not supported");
+ }
+
+ g_module_close (module);
+}
+
static void
do_pre_parse_initialization (int *argc,
char ***argv)
{
const gchar *env_string;
-#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
-
if (pre_initialized)
return;
pre_initialized = TRUE;
+ check_mixed_deps ();
+
gdk_pre_parse_libgtk_only ();
gdk_event_handler_set ((GdkEventFunc)gtk_main_do_event, NULL, NULL);
env_string = g_getenv ("GTK_DEBUG");
if (env_string != NULL)
{
- gtk_debug_flags = g_parse_debug_string (env_string,
- gtk_debug_keys,
- G_N_ELEMENTS (gtk_debug_keys));
+ debug_flags = g_parse_debug_string (env_string,
+ gtk_debug_keys,
+ G_N_ELEMENTS (gtk_debug_keys));
env_string = NULL;
}
#endif /* G_ENABLE_DEBUG */
g_log_set_always_fatal (fatal_mask);
}
- if (gtk_debug_flags & GTK_DEBUG_UPDATES)
+ if (debug_flags & GTK_DEBUG_UPDATES)
gdk_window_set_debug_updates (TRUE);
{
g_type_init ();
_gtk_accel_map_init ();
- _gtk_rc_init ();
/* Set the 'initialized' flag.
*/
}
+/**
+ * gtk_get_debug_flags:
+ *
+ * Returns the GTK+ debug flags.
+ *
+ * This function is intended for GTK+ modules that want
+ * to adjust their debug output based on GTK+ debug flags.
+ *
+ * Returns: the GTK+ debug flags.
+ */
+guint
+gtk_get_debug_flags (void)
+{
+ return debug_flags;
+}
+
+/**
+ * gtk_set_debug_flags:
+ *
+ * Sets the GTK+ debug flags.
+ */
+void
+gtk_set_debug_flags (guint flags)
+{
+ debug_flags = flags;
+}
+
/**
* gtk_get_option_group:
* @open_default_display: whether to open the default display
* @argc: a pointer to the number of command line arguments.
* @argv: a pointer to the array of command line arguments.
* @parameter_string: a string which is displayed in
- * the first line of <option>--help</option> output, after
+ * the first line of <option>--help</option> output, after
* <literal><replaceable>programname</replaceable> [OPTION...]</literal>
* @entries: a %NULL-terminated array of #GOptionEntry<!-- -->s
* describing the options of your program
* @translation_domain: a translation domain to use for translating
* the <option>--help</option> output for the options in @entries
- * with gettext(), or %NULL
- * @error: a return location for errors
+ * and the @parameter_string with gettext(), or %NULL
+ * @error: a return location for errors
*
- * This function does the same work as gtk_init_check().
- * Additionally, it allows you to add your own commandline options,
- * and it automatically generates nicely formatted
+ * This function does the same work as gtk_init_check().
+ * Additionally, it allows you to add your own commandline options,
+ * and it automatically generates nicely formatted
* <option>--help</option> output. Note that your program will
* be terminated after writing out the help output.
*
- * Returns: %TRUE if the GUI has been successfully initialized,
+ * Returns: %TRUE if the GUI has been successfully initialized,
* %FALSE otherwise.
- *
+ *
* Since: 2.6
*/
gboolean
-gtk_init_with_args (int *argc,
- char ***argv,
- const char *parameter_string,
- GOptionEntry *entries,
- const char *translation_domain,
- GError **error)
+gtk_init_with_args (gint *argc,
+ gchar ***argv,
+ const gchar *parameter_string,
+ const GOptionEntry *entries,
+ const gchar *translation_domain,
+ GError **error)
{
GOptionContext *context;
GOptionGroup *gtk_group;
return FALSE;
gtk_group = gtk_get_option_group (TRUE);
-
+
context = g_option_context_new (parameter_string);
g_option_context_add_group (context, gtk_group);
-
+ g_option_context_set_translation_domain (context, translation_domain);
+
if (entries)
g_option_context_add_main_entries (context, entries, translation_domain);
retval = g_option_context_parse (context, argc, argv, error);
-
+
g_option_context_free (context);
return retval;
#endif
-void
-gtk_exit (gint errorcode)
-{
- exit (errorcode);
-}
-
-
/**
* gtk_set_locale:
*
gtk_main (void)
{
GList *tmp_list;
- GList *functions;
- GtkInitFunction *init;
GMainLoop *loop;
gtk_main_loop_level++;
loop = g_main_loop_new (NULL, TRUE);
main_loops = g_slist_prepend (main_loops, loop);
- tmp_list = functions = init_functions;
- init_functions = NULL;
-
- while (tmp_list)
- {
- init = tmp_list->data;
- tmp_list = tmp_list->next;
-
- (* init->function) (init->data);
- g_free (init);
- }
- g_list_free (functions);
-
if (g_main_loop_is_running (main_loops->data))
{
GDK_THREADS_LEAVE ();
/* private libgtk to libgdk interfaces
*/
-gboolean gdk_pointer_grab_info_libgtk_only (GdkDisplay *display,
- GdkWindow **grab_window,
- gboolean *owner_events);
-gboolean gdk_keyboard_grab_info_libgtk_only (GdkDisplay *display,
- GdkWindow **grab_window,
- gboolean *owner_events);
+gboolean gdk_device_grab_info_libgtk_only (GdkDisplay *display,
+ GdkDevice *device,
+ GdkWindow **grab_window,
+ gboolean *owner_events);
static void
rewrite_events_translate (GdkWindow *old_window,
gpointer grab_widget_ptr;
gboolean owner_events;
GdkDisplay *display;
+ GdkDevice *device;
switch (event->type)
{
case GDK_MOTION_NOTIFY:
case GDK_PROXIMITY_IN:
case GDK_PROXIMITY_OUT:
- display = gdk_drawable_get_display (event->proximity.window);
- if (!gdk_pointer_grab_info_libgtk_only (display, &grab_window, &owner_events) ||
- !owner_events)
- return NULL;
- break;
-
case GDK_KEY_PRESS:
case GDK_KEY_RELEASE:
- display = gdk_drawable_get_display (event->key.window);
- if (!gdk_keyboard_grab_info_libgtk_only (display, &grab_window, &owner_events) ||
+ display = gdk_window_get_display (event->any.window);
+ device = gdk_event_get_device (event);
+
+ if (!gdk_device_grab_info_libgtk_only (display, device, &grab_window, &owner_events) ||
!owner_events)
- return NULL;
+ return NULL;
break;
-
default:
return NULL;
}
gtk_main_do_event (GdkEvent *event)
{
GtkWidget *event_widget;
- GtkWidget *grab_widget;
+ GtkWidget *grab_widget = NULL;
GtkWindowGroup *window_group;
GdkEvent *rewritten_event = NULL;
+ GdkDevice *device;
GList *tmp_list;
if (event->type == GDK_SETTING)
event = rewritten_event;
event_widget = gtk_get_event_widget (event);
}
-
+
window_group = gtk_main_get_window_group (event_widget);
+ device = gdk_event_get_device (event);
- /* Push the event onto a stack of current events for
- * gtk_current_event_get().
+ /* check whether there is a (device) grab in effect...
*/
- current_events = g_list_prepend (current_events, event);
+ if (device)
+ grab_widget = gtk_window_group_get_current_device_grab (window_group, device);
- /* If there is a grab in effect...
+ if (!grab_widget)
+ grab_widget = gtk_window_group_get_current_grab (window_group);
+
+ /* 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 (window_group->grabs)
- {
- grab_widget = window_group->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;
- }
- else
+ if (!grab_widget ||
+ (gtk_widget_is_sensitive (event_widget) &&
+ gtk_widget_is_ancestor (event_widget, grab_widget)))
+ grab_widget = event_widget;
+
+ /* If the widget receiving events is actually blocked by another device GTK+ grab */
+ if (device &&
+ _gtk_window_group_widget_is_blocked_for_device (window_group, grab_widget, device))
{
- grab_widget = event_widget;
+ if (rewritten_event)
+ gdk_event_free (rewritten_event);
+
+ return;
}
+ /* Push the event onto a stack of current events for
+ * gtk_current_event_get().
+ */
+ current_events = g_list_prepend (current_events, event);
+
/* 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
case GDK_DELETE:
g_object_ref (event_widget);
- if ((!window_group->grabs || gtk_widget_get_toplevel (window_group->grabs->data) == event_widget) &&
+ if ((!gtk_window_group_get_current_grab (window_group) || gtk_widget_get_toplevel (gtk_window_group_get_current_grab (window_group)) == event_widget) &&
!gtk_widget_event (event_widget, event))
gtk_widget_destroy (event_widget);
g_object_unref (event_widget);
/* Unexpected GDK_DESTROY from the outside, ignore for
* child windows, handle like a GDK_DELETE for toplevels
*/
- if (!event_widget->parent)
+ if (!gtk_widget_get_parent (event_widget))
{
g_object_ref (event_widget);
if (!gtk_widget_event (event_widget, event) &&
- GTK_WIDGET_REALIZED (event_widget))
+ gtk_widget_get_realized (event_widget))
gtk_widget_destroy (event_widget);
g_object_unref (event_widget);
}
{
/* The app may paint with a previously allocated cairo_t,
which will draw directly to the window. We can't catch cairo
- drap operatoins to automatically flush the window, thus we
+ draw operations to automatically flush the window, thus we
need to explicitly flush any outstanding moves or double
buffering */
gdk_window_flush (event->any.window);
break;
case GDK_PROPERTY_NOTIFY:
- case GDK_NO_EXPOSE:
case GDK_FOCUS_CHANGE:
case GDK_CONFIGURE:
case GDK_MAP:
/* Catch alt press to enable auto-mnemonics;
* menus are handled elsewhere
*/
- if ((event->key.keyval == GDK_Alt_L || event->key.keyval == GDK_Alt_R) &&
+ if ((event->key.keyval == GDK_KEY_Alt_L || event->key.keyval == GDK_KEY_Alt_R) &&
!GTK_IS_MENU_SHELL (grab_widget))
{
gboolean auto_mnemonics;
break;
case GDK_ENTER_NOTIFY:
- GTK_PRIVATE_SET_FLAG (event_widget, GTK_HAS_POINTER);
- _gtk_widget_set_pointer_window (event_widget, event->any.window);
+ _gtk_widget_set_device_window (event_widget,
+ gdk_event_get_device (event),
+ event->any.window);
if (gtk_widget_is_sensitive (grab_widget))
gtk_widget_event (grab_widget, event);
break;
case GDK_LEAVE_NOTIFY:
- GTK_PRIVATE_UNSET_FLAG (event_widget, GTK_HAS_POINTER);
+ _gtk_widget_set_device_window (event_widget,
+ gdk_event_get_device (event),
+ NULL);
if (gtk_widget_is_sensitive (grab_widget))
gtk_widget_event (grab_widget, event);
break;
gboolean was_grabbed;
gboolean is_grabbed;
gboolean from_grab;
+ GList *notified_windows;
+ GdkDevice *device;
} GrabNotifyInfo;
+static void
+synth_crossing_for_grab_notify (GtkWidget *from,
+ GtkWidget *to,
+ GrabNotifyInfo *info,
+ GList *devices,
+ GdkCrossingMode mode)
+{
+ while (devices)
+ {
+ GdkDevice *device = devices->data;
+ GdkWindow *from_window, *to_window;
+
+ /* Do not propagate events more than once to
+ * the same windows if non-multidevice aware.
+ */
+ if (!from)
+ from_window = NULL;
+ else
+ {
+ from_window = _gtk_widget_get_device_window (from, device);
+
+ if (from_window &&
+ !gdk_window_get_support_multidevice (from_window) &&
+ g_list_find (info->notified_windows, from_window))
+ from_window = NULL;
+ }
+
+ if (!to)
+ to_window = NULL;
+ else
+ {
+ to_window = _gtk_widget_get_device_window (to, device);
+
+ if (to_window &&
+ !gdk_window_get_support_multidevice (to_window) &&
+ g_list_find (info->notified_windows, to_window))
+ to_window = NULL;
+ }
+
+ if (from_window || to_window)
+ {
+ _gtk_widget_synthesize_crossing ((from_window) ? from : NULL,
+ (to_window) ? to : NULL,
+ device, mode);
+
+ if (from_window)
+ info->notified_windows = g_list_prepend (info->notified_windows, from_window);
+
+ if (to_window)
+ info->notified_windows = g_list_prepend (info->notified_windows, to_window);
+ }
+
+ devices = devices->next;
+ }
+}
+
static void
gtk_grab_notify_foreach (GtkWidget *child,
gpointer data)
-
{
GrabNotifyInfo *info = data;
-
gboolean was_grabbed, is_grabbed, was_shadowed, is_shadowed;
+ GList *devices;
was_grabbed = info->was_grabbed;
is_grabbed = info->is_grabbed;
if ((was_shadowed || is_shadowed) && GTK_IS_CONTAINER (child))
gtk_container_forall (GTK_CONTAINER (child), gtk_grab_notify_foreach, info);
-
+
+ if (info->device &&
+ _gtk_widget_get_device_window (child, info->device))
+ {
+ /* Device specified and is on widget */
+ devices = g_list_prepend (NULL, info->device);
+ }
+ else
+ devices = _gtk_widget_list_devices (child);
+
if (is_shadowed)
{
- GTK_PRIVATE_SET_FLAG (child, GTK_SHADOWED);
- if (!was_shadowed && GTK_WIDGET_HAS_POINTER (child)
- && gtk_widget_is_sensitive (child))
- _gtk_widget_synthesize_crossing (child, info->new_grab_widget,
- GDK_CROSSING_GTK_GRAB);
+ _gtk_widget_set_shadowed (child, TRUE);
+ if (!was_shadowed && devices &&
+ gtk_widget_is_sensitive (child))
+ synth_crossing_for_grab_notify (child, info->new_grab_widget,
+ info, devices,
+ GDK_CROSSING_GTK_GRAB);
}
else
{
- GTK_PRIVATE_UNSET_FLAG (child, GTK_SHADOWED);
- if (was_shadowed && GTK_WIDGET_HAS_POINTER (child)
- && gtk_widget_is_sensitive (child))
- _gtk_widget_synthesize_crossing (info->old_grab_widget, child,
- info->from_grab ? GDK_CROSSING_GTK_GRAB
- : GDK_CROSSING_GTK_UNGRAB);
+ _gtk_widget_set_shadowed (child, FALSE);
+ if (was_shadowed && devices &&
+ gtk_widget_is_sensitive (child))
+ synth_crossing_for_grab_notify (info->old_grab_widget, child,
+ info, devices,
+ info->from_grab ? GDK_CROSSING_GTK_GRAB :
+ GDK_CROSSING_GTK_UNGRAB);
}
if (was_shadowed != is_shadowed)
_gtk_widget_grab_notify (child, was_shadowed);
-
+
g_object_unref (child);
-
+ g_list_free (devices);
+
info->was_grabbed = was_grabbed;
info->is_grabbed = is_grabbed;
}
static void
gtk_grab_notify (GtkWindowGroup *group,
+ GdkDevice *device,
GtkWidget *old_grab_widget,
GtkWidget *new_grab_widget,
gboolean from_grab)
{
GList *toplevels;
- GrabNotifyInfo info;
+ GrabNotifyInfo info = { 0 };
if (old_grab_widget == new_grab_widget)
return;
info.old_grab_widget = old_grab_widget;
info.new_grab_widget = new_grab_widget;
info.from_grab = from_grab;
+ info.device = device;
g_object_ref (group);
toplevels = gtk_window_list_toplevels ();
g_list_foreach (toplevels, (GFunc)g_object_ref, NULL);
-
+
while (toplevels)
{
GtkWindow *toplevel = toplevels->data;
g_object_unref (toplevel);
}
+ g_list_free (info.notified_windows);
g_object_unref (group);
}
if (!gtk_widget_has_grab (widget) && gtk_widget_is_sensitive (widget))
{
- GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_GRAB);
-
+ _gtk_widget_set_has_grab (widget, TRUE);
+
group = gtk_main_get_window_group (widget);
- if (group->grabs)
- old_grab_widget = (GtkWidget *)group->grabs->data;
- else
- old_grab_widget = NULL;
+ old_grab_widget = gtk_window_group_get_current_grab (group);
g_object_ref (widget);
- group->grabs = g_slist_prepend (group->grabs, widget);
+ _gtk_window_group_add_grab (group, widget);
- gtk_grab_notify (group, old_grab_widget, widget, TRUE);
+ gtk_grab_notify (group, NULL, old_grab_widget, widget, TRUE);
}
}
+/**
+ * gtk_grab_get_current:
+ *
+ * Queries the current grab of the default window group.
+ *
+ * Return value: (transfer none): The widget which currently
+ * has the grab or %NULL if no grab is active
+ */
GtkWidget*
gtk_grab_get_current (void)
{
group = gtk_main_get_window_group (NULL);
- if (group->grabs)
- return GTK_WIDGET (group->grabs->data);
- return NULL;
+ return gtk_window_group_get_current_grab (group);
}
void
if (gtk_widget_has_grab (widget))
{
- GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_GRAB);
+ _gtk_widget_set_has_grab (widget, FALSE);
group = gtk_main_get_window_group (widget);
- group->grabs = g_slist_remove (group->grabs, widget);
-
- if (group->grabs)
- new_grab_widget = (GtkWidget *)group->grabs->data;
- else
- new_grab_widget = NULL;
+ _gtk_window_group_remove_grab (group, widget);
+ new_grab_widget = gtk_window_group_get_current_grab (group);
+
+ gtk_grab_notify (group, NULL, widget, new_grab_widget, FALSE);
- gtk_grab_notify (group, widget, new_grab_widget, FALSE);
-
g_object_unref (widget);
}
}
+/**
+ * gtk_device_grab_add:
+ * @widget: a #GtkWidget
+ * @device: a #GtkDevice to grab on.
+ * @block_others: %TRUE to prevent other devices to interact with @widget.
+ *
+ * Adds a GTK+ grab on @device, so all the events on @device and its
+ * associated pointer or keyboard (if any) are delivered to @widget.
+ * If the @block_others parameter is %TRUE, any other devices will be
+ * unable to interact with @widget during the grab.
+ *
+ * Since: 3.0
+ **/
void
-gtk_init_add (GtkFunction function,
- gpointer data)
+gtk_device_grab_add (GtkWidget *widget,
+ GdkDevice *device,
+ gboolean block_others)
{
- GtkInitFunction *init;
-
- init = g_new (GtkInitFunction, 1);
- init->function = function;
- init->data = data;
-
- init_functions = g_list_prepend (init_functions, init);
+ GtkWindowGroup *group;
+ GtkWidget *old_grab_widget;
+
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+ g_return_if_fail (GDK_IS_DEVICE (device));
+
+ group = gtk_main_get_window_group (widget);
+ old_grab_widget = gtk_window_group_get_current_device_grab (group, device);
+
+ if (old_grab_widget != widget)
+ _gtk_window_group_add_device_grab (group, widget, device, block_others);
+
+ gtk_grab_notify (group, device, old_grab_widget, widget, TRUE);
+}
+
+/**
+ * gtk_device_grab_remove:
+ * @widget: a #GtkWidget
+ * @device: a #GdkDevice
+ *
+ * Removes a device grab from the given widget. You have to pair calls
+ * to gtk_device_grab_add() and gtk_device_grab_remove().
+ *
+ * Since: 3.0
+ **/
+void
+gtk_device_grab_remove (GtkWidget *widget,
+ GdkDevice *device)
+{
+ GtkWindowGroup *group;
+ GtkWidget *new_grab_widget;
+
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+ g_return_if_fail (GDK_IS_DEVICE (device));
+
+ group = gtk_main_get_window_group (widget);
+ _gtk_window_group_remove_device_grab (group, widget, device);
+ new_grab_widget = gtk_window_group_get_current_device_grab (group, device);
+
+ gtk_grab_notify (group, device, widget, new_grab_widget, FALSE);
}
guint
}
static gint
-gtk_quit_destructor (GtkObject **object_p)
+gtk_quit_destructor (GtkWidget **object_p)
{
if (*object_p)
- gtk_object_destroy (*object_p);
+ gtk_widget_destroy (*object_p);
g_free (object_p);
return FALSE;
}
void
-gtk_quit_add_destroy (guint main_level,
- GtkObject *object)
+gtk_quit_add_destroy (guint main_level,
+ GtkWidget *object)
{
- GtkObject **object_p;
+ GtkWidget **object_p;
g_return_if_fail (main_level > 0);
- g_return_if_fail (GTK_IS_OBJECT (object));
+ g_return_if_fail (GTK_IS_WIDGET (object));
- object_p = g_new (GtkObject*, 1);
+ object_p = g_new (GtkWidget*, 1);
*object_p = object;
g_signal_connect (object,
"destroy",
}
}
-guint
-gtk_timeout_add_full (guint32 interval,
- GtkFunction function,
- GtkCallbackMarshal marshal,
- gpointer data,
- GDestroyNotify destroy)
-{
- if (marshal)
- {
- GtkClosure *closure;
-
- closure = g_new (GtkClosure, 1);
- closure->marshal = marshal;
- closure->data = data;
- closure->destroy = destroy;
-
- return g_timeout_add_full (0, interval,
- gtk_invoke_idle_timeout,
- closure,
- gtk_destroy_closure);
- }
- else
- return g_timeout_add_full (0, interval, function, data, destroy);
-}
-
-guint
-gtk_timeout_add (guint32 interval,
- GtkFunction function,
- gpointer data)
-{
- return g_timeout_add_full (0, interval, function, data, NULL);
-}
-
-void
-gtk_timeout_remove (guint tag)
-{
- g_source_remove (tag);
-}
-
-guint
-gtk_idle_add_full (gint priority,
- GtkFunction function,
- GtkCallbackMarshal marshal,
- gpointer data,
- GDestroyNotify destroy)
-{
- if (marshal)
- {
- GtkClosure *closure;
-
- closure = g_new (GtkClosure, 1);
- closure->marshal = marshal;
- closure->data = data;
- closure->destroy = destroy;
-
- return g_idle_add_full (priority,
- gtk_invoke_idle_timeout,
- closure,
- gtk_destroy_closure);
- }
- else
- return g_idle_add_full (priority, function, data, destroy);
-}
-
-guint
-gtk_idle_add (GtkFunction function,
- gpointer data)
-{
- return g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, function, data, NULL);
-}
-
-guint
-gtk_idle_add_priority (gint priority,
- GtkFunction function,
- gpointer data)
-{
- 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,
- GDestroyNotify destroy)
-{
- if (marshal)
- {
- GtkClosure *closure;
-
- closure = g_new (GtkClosure, 1);
- closure->marshal = marshal;
- closure->data = data;
- closure->destroy = destroy;
-
- return gdk_input_add_full (source,
- condition,
- (GdkInputFunction) gtk_invoke_input,
- closure,
- (GDestroyNotify) gtk_destroy_closure);
- }
- else
- return gdk_input_add_full (source, condition, function, data, destroy);
-}
-
-void
-gtk_input_remove (guint 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 = G_TYPE_BOOLEAN;
- args[0].d.pointer_data = &ret_val;
- closure->marshal (NULL, closure->data, 0, args);
- return ret_val;
-}
-
-static void
-gtk_invoke_input (gpointer data,
- gint source,
- GdkInputCondition condition)
-{
- GtkClosure *closure = data;
-
- GtkArg args[3];
- args[0].type = G_TYPE_INT;
- args[0].name = NULL;
- GTK_VALUE_INT (args[0]) = source;
- args[1].type = GDK_TYPE_INPUT_CONDITION;
- args[1].name = NULL;
- GTK_VALUE_FLAGS (args[1]) = condition;
- args[2].type = G_TYPE_NONE;
- args[2].name = NULL;
-
- closure->marshal (NULL, closure->data, 2, args);
-}
-
/**
* gtk_get_current_event:
*
}
}
+/**
+ * gtk_get_current_event_device:
+ *
+ * If there is a current event and it has a device, return that
+ * device, otherwise return %NULL.
+ *
+ * Returns: (transfer none): a #GdkDevice, or %NULL
+ **/
+GdkDevice *
+gtk_get_current_event_device (void)
+{
+ if (current_events)
+ return gdk_event_get_device (current_events->data);
+ else
+ return NULL;
+}
+
/**
* gtk_get_event_widget:
* @event: a #GdkEvent
* returns %NULL, otherwise returns the widget that received the event
* originally.
*
- * Return value: the widget that originally received @event, or %NULL
+ * Return value: (transfer none): the widget that originally
+ * received @event, or %NULL
**/
GtkWidget*
gtk_get_event_widget (GdkEvent *event)
widget = NULL;
if (event && event->any.window &&
- (event->type == GDK_DESTROY || !GDK_WINDOW_DESTROYED (event->any.window)))
+ (event->type == GDK_DESTROY || !gdk_window_is_destroyed (event->any.window)))
{
gdk_window_get_user_data (event->any.window, &widget_ptr);
widget = widget_ptr;
handled_event = event->type != GDK_SCROLL;
else
handled_event = gtk_widget_event (widget, event);
-
- tmp = widget->parent;
+
+ tmp = gtk_widget_get_parent (widget);
g_object_unref (widget);
widget = tmp;
g_object_unref (widget);
}
-#if 0
-static void
-gtk_error (gchar *str)
-{
- gtk_print (str);
-}
-
-static void
-gtk_warning (gchar *str)
-{
- gtk_print (str);
-}
-
-static void
-gtk_message (gchar *str)
-{
- gtk_print (str);
-}
-
-static void
-gtk_print (gchar *str)
-{
- static GtkWidget *window = NULL;
- static GtkWidget *text;
- static int level = 0;
- GtkWidget *box1;
- GtkWidget *box2;
- GtkWidget *table;
- GtkWidget *hscrollbar;
- GtkWidget *vscrollbar;
- GtkWidget *separator;
- GtkWidget *button;
-
- if (level > 0)
- {
- fputs (str, stdout);
- fflush (stdout);
- return;
- }
-
- if (!window)
- {
- window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-
- gtk_signal_connect (GTK_OBJECT (window), "destroy",
- G_CALLBACK (gtk_widget_destroyed),
- &window);
-
- gtk_window_set_title (GTK_WINDOW (window), "Messages");
-
- box1 = gtk_vbox_new (FALSE, 0);
- gtk_container_add (GTK_CONTAINER (window), box1);
- gtk_widget_show (box1);
-
-
- box2 = gtk_vbox_new (FALSE, 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);
-
-
- table = gtk_table_new (2, 2, FALSE);
- gtk_table_set_row_spacing (GTK_TABLE (table), 0, 2);
- gtk_table_set_col_spacing (GTK_TABLE (table), 0, 2);
- gtk_box_pack_start (GTK_BOX (box2), table, TRUE, TRUE, 0);
- gtk_widget_show (table);
-
- text = gtk_text_new (NULL, NULL);
- gtk_text_set_editable (GTK_TEXT (text), FALSE);
- gtk_table_attach_defaults (GTK_TABLE (table), text, 0, 1, 0, 1);
- gtk_widget_show (text);
- gtk_widget_realize (text);
-
- hscrollbar = gtk_hscrollbar_new (GTK_TEXT (text)->hadj);
- gtk_table_attach (GTK_TABLE (table), hscrollbar, 0, 1, 1, 2,
- GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
- gtk_widget_show (hscrollbar);
-
- vscrollbar = gtk_vscrollbar_new (GTK_TEXT (text)->vadj);
- gtk_table_attach (GTK_TABLE (table), vscrollbar, 1, 2, 0, 1,
- GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
- gtk_widget_show (vscrollbar);
-
- separator = gtk_hseparator_new ();
- gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
- gtk_widget_show (separator);
-
-
- box2 = gtk_vbox_new (FALSE, 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);
-
-
- button = gtk_button_new_with_label ("close");
- gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
- G_CALLBACK (gtk_widget_hide),
- GTK_OBJECT (window));
- gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
- gtk_widget_set_can_default (button, TRUE);
- gtk_widget_grab_default (button);
- gtk_widget_show (button);
- }
-
- level += 1;
- gtk_text_insert (GTK_TEXT (text), NULL, NULL, NULL, str, -1);
- level -= 1;
-
- if (!gtk_widget_get_visible (window))
- gtk_widget_show (window);
-}
-#endif
-
gboolean
_gtk_boolean_handled_accumulator (GSignalInvocationHint *ihint,
GValue *return_accu,
return continue_emission;
}
-
-#define __GTK_MAIN_C__
-#include "gtkaliasdef.c"