diff options
46 files changed, 1033 insertions, 5329 deletions
@@ -1,3 +1,41 @@ +Tue Dec 15 01:38:53 1998 Owen Taylor <otaylor@redhat.com> + + * gtk/Makefile.am: Commented out testthreads from + the build process, since we won't have any idea + how to create a thread. + + * configure.in (LIBS): use glib-config ... gthread + so we always build a thread-compatible library. + + * gtk/gtkaccellabel.c gtk/gtkclist.c gtk/gtkcolorsel.c + gtk/gtkcombo.c gtk/gtkcontainer.c gtk/gtkentry.c + gtk/gtklist.c gtk/gtkmenuitem.c gtk/gtknotebook.c + gtk/gtkrange.c gtk/gtkselection.c gtk/gtkspinbutton.c + gtk/gtktext.c gtk/gtktooltips.c gtk/gtkwidget.c: + + Add GTK_THREADS_ENTER/LEAVE pairs around timeouts + and idles to account for the fact that they are no + longer called within the GTK+ lock. + + * gtk/gtkprivate.h: Added definitions for locking + the main GTK+ mutex. + + * gtk/gtkmain.c: Re-implement the main loop + in terms of the GLib main loop. + + * gdk/gdk.h gdk/gdkthreads.c gdk/Makefile.am: Removed threading + functionality, as it seems better to subsume GDK within the + GTK+ lock than vice-versa. + + * gdk/gdkevents.c: New file, containing event handling bits + from gdk.c. + + * gdk/gdkevents.c: Implement event source for GDK + events. + + * configure.in gdk/gdkevents.c: Removed attempts to + subtract base_id, which were already non-functional. + Mon Dec 14 23:05:20 PST 1998 Manish Singh <yosh@gimp.org> * acconfig.h @@ -871,6 +909,8 @@ Tue Nov 24 11:31:06 1998 Owen Taylor <otaylor@redhat.com> * testgtk.c: Modified layout test to test scrolling over long distances. + * gtk/gtkplug.c: Added a few blank lines. + Tue Nov 24 11:11:05 1998 Owen Taylor <otaylor@redhat.com> * gtk/gtklayout.[ch]: Fixed up copyright message. diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index d101dbb00a..992a64f6b3 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,3 +1,41 @@ +Tue Dec 15 01:38:53 1998 Owen Taylor <otaylor@redhat.com> + + * gtk/Makefile.am: Commented out testthreads from + the build process, since we won't have any idea + how to create a thread. + + * configure.in (LIBS): use glib-config ... gthread + so we always build a thread-compatible library. + + * gtk/gtkaccellabel.c gtk/gtkclist.c gtk/gtkcolorsel.c + gtk/gtkcombo.c gtk/gtkcontainer.c gtk/gtkentry.c + gtk/gtklist.c gtk/gtkmenuitem.c gtk/gtknotebook.c + gtk/gtkrange.c gtk/gtkselection.c gtk/gtkspinbutton.c + gtk/gtktext.c gtk/gtktooltips.c gtk/gtkwidget.c: + + Add GTK_THREADS_ENTER/LEAVE pairs around timeouts + and idles to account for the fact that they are no + longer called within the GTK+ lock. + + * gtk/gtkprivate.h: Added definitions for locking + the main GTK+ mutex. + + * gtk/gtkmain.c: Re-implement the main loop + in terms of the GLib main loop. + + * gdk/gdk.h gdk/gdkthreads.c gdk/Makefile.am: Removed threading + functionality, as it seems better to subsume GDK within the + GTK+ lock than vice-versa. + + * gdk/gdkevents.c: New file, containing event handling bits + from gdk.c. + + * gdk/gdkevents.c: Implement event source for GDK + events. + + * configure.in gdk/gdkevents.c: Removed attempts to + subtract base_id, which were already non-functional. + Mon Dec 14 23:05:20 PST 1998 Manish Singh <yosh@gimp.org> * acconfig.h @@ -871,6 +909,8 @@ Tue Nov 24 11:31:06 1998 Owen Taylor <otaylor@redhat.com> * testgtk.c: Modified layout test to test scrolling over long distances. + * gtk/gtkplug.c: Added a few blank lines. + Tue Nov 24 11:11:05 1998 Owen Taylor <otaylor@redhat.com> * gtk/gtklayout.[ch]: Fixed up copyright message. diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index d101dbb00a..992a64f6b3 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,41 @@ +Tue Dec 15 01:38:53 1998 Owen Taylor <otaylor@redhat.com> + + * gtk/Makefile.am: Commented out testthreads from + the build process, since we won't have any idea + how to create a thread. + + * configure.in (LIBS): use glib-config ... gthread + so we always build a thread-compatible library. + + * gtk/gtkaccellabel.c gtk/gtkclist.c gtk/gtkcolorsel.c + gtk/gtkcombo.c gtk/gtkcontainer.c gtk/gtkentry.c + gtk/gtklist.c gtk/gtkmenuitem.c gtk/gtknotebook.c + gtk/gtkrange.c gtk/gtkselection.c gtk/gtkspinbutton.c + gtk/gtktext.c gtk/gtktooltips.c gtk/gtkwidget.c: + + Add GTK_THREADS_ENTER/LEAVE pairs around timeouts + and idles to account for the fact that they are no + longer called within the GTK+ lock. + + * gtk/gtkprivate.h: Added definitions for locking + the main GTK+ mutex. + + * gtk/gtkmain.c: Re-implement the main loop + in terms of the GLib main loop. + + * gdk/gdk.h gdk/gdkthreads.c gdk/Makefile.am: Removed threading + functionality, as it seems better to subsume GDK within the + GTK+ lock than vice-versa. + + * gdk/gdkevents.c: New file, containing event handling bits + from gdk.c. + + * gdk/gdkevents.c: Implement event source for GDK + events. + + * configure.in gdk/gdkevents.c: Removed attempts to + subtract base_id, which were already non-functional. + Mon Dec 14 23:05:20 PST 1998 Manish Singh <yosh@gimp.org> * acconfig.h @@ -871,6 +909,8 @@ Tue Nov 24 11:31:06 1998 Owen Taylor <otaylor@redhat.com> * testgtk.c: Modified layout test to test scrolling over long distances. + * gtk/gtkplug.c: Added a few blank lines. + Tue Nov 24 11:11:05 1998 Owen Taylor <otaylor@redhat.com> * gtk/gtklayout.[ch]: Fixed up copyright message. diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index d101dbb00a..992a64f6b3 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,41 @@ +Tue Dec 15 01:38:53 1998 Owen Taylor <otaylor@redhat.com> + + * gtk/Makefile.am: Commented out testthreads from + the build process, since we won't have any idea + how to create a thread. + + * configure.in (LIBS): use glib-config ... gthread + so we always build a thread-compatible library. + + * gtk/gtkaccellabel.c gtk/gtkclist.c gtk/gtkcolorsel.c + gtk/gtkcombo.c gtk/gtkcontainer.c gtk/gtkentry.c + gtk/gtklist.c gtk/gtkmenuitem.c gtk/gtknotebook.c + gtk/gtkrange.c gtk/gtkselection.c gtk/gtkspinbutton.c + gtk/gtktext.c gtk/gtktooltips.c gtk/gtkwidget.c: + + Add GTK_THREADS_ENTER/LEAVE pairs around timeouts + and idles to account for the fact that they are no + longer called within the GTK+ lock. + + * gtk/gtkprivate.h: Added definitions for locking + the main GTK+ mutex. + + * gtk/gtkmain.c: Re-implement the main loop + in terms of the GLib main loop. + + * gdk/gdk.h gdk/gdkthreads.c gdk/Makefile.am: Removed threading + functionality, as it seems better to subsume GDK within the + GTK+ lock than vice-versa. + + * gdk/gdkevents.c: New file, containing event handling bits + from gdk.c. + + * gdk/gdkevents.c: Implement event source for GDK + events. + + * configure.in gdk/gdkevents.c: Removed attempts to + subtract base_id, which were already non-functional. + Mon Dec 14 23:05:20 PST 1998 Manish Singh <yosh@gimp.org> * acconfig.h @@ -871,6 +909,8 @@ Tue Nov 24 11:31:06 1998 Owen Taylor <otaylor@redhat.com> * testgtk.c: Modified layout test to test scrolling over long distances. + * gtk/gtkplug.c: Added a few blank lines. + Tue Nov 24 11:11:05 1998 Owen Taylor <otaylor@redhat.com> * gtk/gtklayout.[ch]: Fixed up copyright message. diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index d101dbb00a..992a64f6b3 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,41 @@ +Tue Dec 15 01:38:53 1998 Owen Taylor <otaylor@redhat.com> + + * gtk/Makefile.am: Commented out testthreads from + the build process, since we won't have any idea + how to create a thread. + + * configure.in (LIBS): use glib-config ... gthread + so we always build a thread-compatible library. + + * gtk/gtkaccellabel.c gtk/gtkclist.c gtk/gtkcolorsel.c + gtk/gtkcombo.c gtk/gtkcontainer.c gtk/gtkentry.c + gtk/gtklist.c gtk/gtkmenuitem.c gtk/gtknotebook.c + gtk/gtkrange.c gtk/gtkselection.c gtk/gtkspinbutton.c + gtk/gtktext.c gtk/gtktooltips.c gtk/gtkwidget.c: + + Add GTK_THREADS_ENTER/LEAVE pairs around timeouts + and idles to account for the fact that they are no + longer called within the GTK+ lock. + + * gtk/gtkprivate.h: Added definitions for locking + the main GTK+ mutex. + + * gtk/gtkmain.c: Re-implement the main loop + in terms of the GLib main loop. + + * gdk/gdk.h gdk/gdkthreads.c gdk/Makefile.am: Removed threading + functionality, as it seems better to subsume GDK within the + GTK+ lock than vice-versa. + + * gdk/gdkevents.c: New file, containing event handling bits + from gdk.c. + + * gdk/gdkevents.c: Implement event source for GDK + events. + + * configure.in gdk/gdkevents.c: Removed attempts to + subtract base_id, which were already non-functional. + Mon Dec 14 23:05:20 PST 1998 Manish Singh <yosh@gimp.org> * acconfig.h @@ -871,6 +909,8 @@ Tue Nov 24 11:31:06 1998 Owen Taylor <otaylor@redhat.com> * testgtk.c: Modified layout test to test scrolling over long distances. + * gtk/gtkplug.c: Added a few blank lines. + Tue Nov 24 11:11:05 1998 Owen Taylor <otaylor@redhat.com> * gtk/gtklayout.[ch]: Fixed up copyright message. diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index d101dbb00a..992a64f6b3 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,41 @@ +Tue Dec 15 01:38:53 1998 Owen Taylor <otaylor@redhat.com> + + * gtk/Makefile.am: Commented out testthreads from + the build process, since we won't have any idea + how to create a thread. + + * configure.in (LIBS): use glib-config ... gthread + so we always build a thread-compatible library. + + * gtk/gtkaccellabel.c gtk/gtkclist.c gtk/gtkcolorsel.c + gtk/gtkcombo.c gtk/gtkcontainer.c gtk/gtkentry.c + gtk/gtklist.c gtk/gtkmenuitem.c gtk/gtknotebook.c + gtk/gtkrange.c gtk/gtkselection.c gtk/gtkspinbutton.c + gtk/gtktext.c gtk/gtktooltips.c gtk/gtkwidget.c: + + Add GTK_THREADS_ENTER/LEAVE pairs around timeouts + and idles to account for the fact that they are no + longer called within the GTK+ lock. + + * gtk/gtkprivate.h: Added definitions for locking + the main GTK+ mutex. + + * gtk/gtkmain.c: Re-implement the main loop + in terms of the GLib main loop. + + * gdk/gdk.h gdk/gdkthreads.c gdk/Makefile.am: Removed threading + functionality, as it seems better to subsume GDK within the + GTK+ lock than vice-versa. + + * gdk/gdkevents.c: New file, containing event handling bits + from gdk.c. + + * gdk/gdkevents.c: Implement event source for GDK + events. + + * configure.in gdk/gdkevents.c: Removed attempts to + subtract base_id, which were already non-functional. + Mon Dec 14 23:05:20 PST 1998 Manish Singh <yosh@gimp.org> * acconfig.h @@ -871,6 +909,8 @@ Tue Nov 24 11:31:06 1998 Owen Taylor <otaylor@redhat.com> * testgtk.c: Modified layout test to test scrolling over long distances. + * gtk/gtkplug.c: Added a few blank lines. + Tue Nov 24 11:11:05 1998 Owen Taylor <otaylor@redhat.com> * gtk/gtklayout.[ch]: Fixed up copyright message. diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index d101dbb00a..992a64f6b3 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,41 @@ +Tue Dec 15 01:38:53 1998 Owen Taylor <otaylor@redhat.com> + + * gtk/Makefile.am: Commented out testthreads from + the build process, since we won't have any idea + how to create a thread. + + * configure.in (LIBS): use glib-config ... gthread + so we always build a thread-compatible library. + + * gtk/gtkaccellabel.c gtk/gtkclist.c gtk/gtkcolorsel.c + gtk/gtkcombo.c gtk/gtkcontainer.c gtk/gtkentry.c + gtk/gtklist.c gtk/gtkmenuitem.c gtk/gtknotebook.c + gtk/gtkrange.c gtk/gtkselection.c gtk/gtkspinbutton.c + gtk/gtktext.c gtk/gtktooltips.c gtk/gtkwidget.c: + + Add GTK_THREADS_ENTER/LEAVE pairs around timeouts + and idles to account for the fact that they are no + longer called within the GTK+ lock. + + * gtk/gtkprivate.h: Added definitions for locking + the main GTK+ mutex. + + * gtk/gtkmain.c: Re-implement the main loop + in terms of the GLib main loop. + + * gdk/gdk.h gdk/gdkthreads.c gdk/Makefile.am: Removed threading + functionality, as it seems better to subsume GDK within the + GTK+ lock than vice-versa. + + * gdk/gdkevents.c: New file, containing event handling bits + from gdk.c. + + * gdk/gdkevents.c: Implement event source for GDK + events. + + * configure.in gdk/gdkevents.c: Removed attempts to + subtract base_id, which were already non-functional. + Mon Dec 14 23:05:20 PST 1998 Manish Singh <yosh@gimp.org> * acconfig.h @@ -871,6 +909,8 @@ Tue Nov 24 11:31:06 1998 Owen Taylor <otaylor@redhat.com> * testgtk.c: Modified layout test to test scrolling over long distances. + * gtk/gtkplug.c: Added a few blank lines. + Tue Nov 24 11:11:05 1998 Owen Taylor <otaylor@redhat.com> * gtk/gtklayout.[ch]: Fixed up copyright message. diff --git a/config.h.in b/config.h.in index 3b83ab3a03..600d96c43a 100644 --- a/config.h.in +++ b/config.h.in @@ -66,11 +66,6 @@ #undef NO_FD_SET -#undef RESOURCE_BASE - -/* Define to enable POSIX threading awareness */ -#undef USE_PTHREADS - #undef XINPUT_NONE #undef XINPUT_GXI #undef XINPUT_XFREE diff --git a/configure.in b/configure.in index b0ede74d8e..608af04c61 100644 --- a/configure.in +++ b/configure.in @@ -184,7 +184,7 @@ if test x$with_glib = x ; then AC_MSG_ERROR([ *** GLIB 1.1.6 or better is required. The latest version of GLIB *** is always available from ftp://ftp.gtk.org.]), - gmodule) + gmodule gthread) glib_cflags=$GLIB_CFLAGS glib_libs=$GLIB_LIBS @@ -305,20 +305,6 @@ else AC_DEFINE(XINPUT_NONE) fi -# Threads - -if test "x$with_threads" = "xposix" || test "x$with_threads" = "xyes"; then - AC_CHECK_LIB(pthread, pthread_attr_init, - [AC_DEFINE(USE_PTHREADS) - x_libs="$x_libs -lpthread" - GTK_THREAD_FLAGS="-D_REENTRANT"], - # AIX has libpthreads, cause they're special. Special friends (TM) - AC_CHECK_LIB(pthreads, pthread_attr_init, - [AC_DEFINE(USE_PTHREADS) - x_libs="$x_libs -lpthreads" - GTK_THREAD_FLAGS="-D_REENTRANT -D_THREAD_SAFE"])) -fi - CFLAGS="$saved_cflags" LDFLAGS="$saved_ldflags" @@ -349,27 +335,6 @@ if test "x$enable_shm" = "xyes"; then fi fi -# Check for private display resource base variable -AC_MSG_CHECKING(resource base field in XDisplay) -AC_CACHE_VAL(gtk_cv_display_resource_base, -[AC_TRY_RUN([ -#define XLIB_ILLEGAL_ACCESS -#include <X11/Xlib.h> - -int -main () -{ - Display *display; - - return 0; - - display->resource_base; -}], -gtk_cv_display_resource_base="resource_base", -gtk_cv_display_resource_base="private3")]) -AC_MSG_RESULT($gtk_cv_display_resource_base) -AC_DEFINE_UNQUOTED(RESOURCE_BASE, gdk_display->$gtk_cv_display_resource_base) - # Check if X_LOCALE definition is necessary AC_MSG_CHECKING(need -DX_LOCALE) diff --git a/docs/Changes-1.2.txt b/docs/Changes-1.2.txt index 50fd3dcecf..afd6e02ef9 100644 --- a/docs/Changes-1.2.txt +++ b/docs/Changes-1.2.txt @@ -84,23 +84,76 @@ Incompatible Changes from GTK+-1.0 to GTK+-1.2: Window. The scrollbar policy is set on the scrolled window with gtk_scrolled_window_set_policy() and not on the child widgets (e.g. GtkCList's gtk_clist_set_policy() was removed). + +* The "main loop" of GTK+ has been moved to GLib. This should not + affect existing programs, since compatibility functions have + been provided. However, you may want to consider migrating + your code to use the GLib main loop directly. + + Minor known incompatibilities: -* the GTK_BASIC flag got removed, and with it the corresponding + - gtk_idle_remove_by_data() and gtk_timeout_remove_by_data() now + work from a common pool of "input sources", so + gtk_idle_remove_by_data() will remove timeouts and + vice-versa. + +* the GTK_BASIC flag was removed, and with it the corresponding macro and function GTK_WIDGET_BASIC() and gtk_widget_basic(). -* all freeze/thaw methods in gtk work in an incremental way now. - code portions like: +* All freeze/thaw methods are now recursive - that is, if you + freeze a widget n times, you must also thaw it n times. + + Therefore, if you have code like: + gboolean frozen; frozen = GTK_CLIST_FROZEN (clist); gtk_clist_freeze (clist); [...] if (!frozen) gtk_clist_thaw (clist); - will not work anymore, they have to be modified to simply: + + it will not work anymore. It must be, simply: + gtk_clist_freeze (clist); [...] gtk_clist_thaw (clist); +* The thread safety in GTK+ 1.2 is slightly different than + that which appeared in early versions in the 1.1 + development track. The main difference is that it relies on + the thread primitives in GLib, and on the thread-safe + GLib main loop. + + This means: + + - You must call g_thread_init(), then gtk_thread_init() + in a threaded GTK+ program. + + - Idles, timeouts, and input functions are executed outside + of the main GTK+ lock. So, if you need to call GTK+ + inside of such a callback, you must surround the callback + with a gtk_thread_enter()/gtk_thread_leave() pair. + + [ However, signals are still executed within the main + GTK+ lock ] + + In particular, this means, if you are writing widgets + that might be used in threaded programs, you _must_ + surround timeouts and idle functions in this matter. + + - There is no longer a special --with-threads configure + option for GTK+. To use threads in a GTK+ program, you + must: + + a) If you want to use the native thread implementation, + make sure GLib found this in configuration, otherwise, + call you must provide a thread implementation to + g_thread_init(). + + b) Link with the libraries returned by: + + gtk-config --libs gthread + * All functions matching g_message* are deprecated * Functions *_interp are deprecated, *_full variants are available diff --git a/gdk/Makefile.am b/gdk/Makefile.am index 2766b3781a..eb71e8e11b 100644 --- a/gdk/Makefile.am +++ b/gdk/Makefile.am @@ -21,6 +21,7 @@ libgdk_la_SOURCES = \ gdkcursor.c \ gdkdnd.c \ gdkdraw.c \ + gdkevents.c \ gdkfont.c \ gdkgc.c \ gdkglobals.c \ @@ -38,7 +39,6 @@ libgdk_la_SOURCES = \ gdkrectangle.c \ gdkregion.c \ gdkselection.c \ - gdkthreads.c \ gdkvisual.c \ gdkwindow.c \ gdkxid.c \ @@ -39,48 +39,16 @@ #include "gdk.h" #include "gdkprivate.h" #include "gdkinput.h" -#include "gdki18n.h" #include "gdkx.h" -#include "gdkkeysyms.h" +#include "gdki18n.h" #ifndef X_GETTIMEOFDAY #define X_GETTIMEOFDAY(tv) gettimeofday (tv, NULL) #endif /* X_GETTIMEOFDAY */ -#define DOUBLE_CLICK_TIME 250 -#define TRIPLE_CLICK_TIME 500 -#define DOUBLE_CLICK_DIST 5 -#define TRIPLE_CLICK_DIST 5 - - -#ifndef NO_FD_SET -# define SELECT_MASK fd_set -#else -# ifndef _AIX -typedef long fd_mask; -# endif -# if defined(_IBMR2) -# define SELECT_MASK void -# else -# define SELECT_MASK int -# endif -#endif - - -typedef struct _GdkInput GdkInput; typedef struct _GdkPredicate GdkPredicate; -struct _GdkInput -{ - gint tag; - gint source; - GdkInputCondition condition; - GdkInputFunction function; - gpointer data; - GdkDestroyNotify destroy; -}; - struct _GdkPredicate { GdkEventFunc func; @@ -91,21 +59,6 @@ struct _GdkPredicate * Private function declarations */ -static GdkEvent *gdk_event_new (void); -static gint gdk_event_wait (void); -static gint gdk_event_apply_filters (XEvent *xevent, - GdkEvent *event, - GList *filters); -static gint gdk_event_translate (GdkEvent *event, - XEvent *xevent); -#if 0 -static Bool gdk_event_get_type (Display *display, - XEvent *xevent, - XPointer arg); -#endif -static void gdk_synthesize_click (GdkEvent *event, - gint nclicks); - #ifndef HAVE_XCONVERTCASE static void gdkx_XConvertCase (KeySym symbol, KeySym *lower, @@ -113,16 +66,6 @@ static void gdkx_XConvertCase (KeySym symbol, #define XConvertCase gdkx_XConvertCase #endif -/* - * old junk from offix, we might use it though so leave it - */ -Window gdk_get_client_window (Display *dpy, - Window win); -#ifdef WE_HAVE_MOTIF_DROPS_DONE -static GdkWindow * gdk_drop_get_real_window (GdkWindow *w, - guint16 *x, - guint16 *y); -#endif static void gdk_exit_func (void); static int gdk_x_error (Display *display, XErrorEvent *error); @@ -137,13 +80,6 @@ GdkFilterReturn gdk_wm_protocols_filter (GdkXEvent *xev, static int gdk_initialized = 0; /* 1 if the library is initialized, * 0 otherwise. */ -static int connection_number = 0; /* The file descriptor number of our - * connection to the X server. This - * is used so that we may determine - * when events are pending by using - * the "select" system call. - */ - static struct timeval start; /* The time at which the library was * last initialized. @@ -162,33 +98,7 @@ static struct timeval *timerp; /* The actual timer passed to "select" static guint32 timer_val; /* The timeout length as specified by * the user in milliseconds. */ -static GList *inputs; /* A list of the input file descriptors - * that we care about. Each list node - * contains a GdkInput struct that describes - * when we are interested in the specified - * file descriptor. That is, when it is - * available for read, write or has an - * exception pending. - */ -static guint32 button_click_time[2]; /* The last 2 button click times. Used - * to determine if the latest button click - * is part of a double or triple click. - */ -static GdkWindow *button_window[2]; /* The last 2 windows to receive button presses. - * Also used to determine if the latest button - * click is part of a double or triple click. - */ -static guint button_number[2]; /* The last 2 buttons to be pressed. - */ -static GdkWindowPrivate *xgrab_window = NULL; /* Window that currently holds the - * x pointer grab - */ -static GList *client_filters; /* Filters for client messages */ - -static GList *putback_events = NULL; - -static gulong base_id; static gint autorepeat; #ifdef G_ENABLE_DEBUG @@ -454,18 +364,6 @@ gdk_init (int *argc, exit(1); } - /* This is really crappy. We have to look into the display structure - * to find the base resource id. This is only needed for recording - * and playback of events. - */ - /* base_id = RESOURCE_BASE; */ - base_id = 0; - GDK_NOTE (EVENTS, g_message ("base id: %lu", base_id)); - - connection_number = ConnectionNumber (gdk_display); - GDK_NOTE (MISC, - g_message ("connection number: %d", connection_number)); - if (synchronize) XSynchronize (gdk_display, True); @@ -504,24 +402,15 @@ gdk_init (int *argc, timer.tv_usec = 0; timerp = NULL; - button_click_time[0] = 0; - button_click_time[1] = 0; - button_window[0] = NULL; - button_window[1] = NULL; - button_number[0] = -1; - button_number[1] = -1; - g_atexit (gdk_exit_func); + gdk_events_init (); gdk_visual_init (); gdk_window_init (); gdk_image_init (); gdk_input_init (); gdk_dnd_init (); - gdk_add_client_message_filter (gdk_wm_protocols, - gdk_wm_protocols_filter, NULL); - #ifdef USE_XIM gdk_im_open (); #endif @@ -589,630 +478,6 @@ gdk_set_locale (void) return setlocale (LC_ALL,NULL); } -/* - *-------------------------------------------------------------- - * gdk_events_pending - * - * Returns the number of events pending on the queue. - * These events have already been read from the server - * connection. - * - * Arguments: - * - * Results: - * Returns the number of events on XLib's event queue. - * - * Side effects: - * - *-------------------------------------------------------------- - */ - -gint -gdk_events_pending (void) -{ - gint result; - GList *tmp_list; - - result = XPending (gdk_display); - - tmp_list = putback_events; - while (tmp_list) - { - result++; - tmp_list = tmp_list->next; - } - - return result; -} - -/* - *-------------------------------------------------------------- - * gdk_event_get_graphics_expose - * - * Waits for a GraphicsExpose or NoExpose event - * - * Arguments: - * - * Results: - * For GraphicsExpose events, returns a pointer to the event - * converted into a GdkEvent Otherwise, returns NULL. - * - * Side effects: - * - *-------------------------------------------------------------- */ - -static Bool -graphics_expose_predicate (Display *display, - XEvent *xevent, - XPointer arg) -{ - GdkWindowPrivate *private = (GdkWindowPrivate *)arg; - - g_return_val_if_fail (private != NULL, False); - - if ((xevent->xany.window == private->xwindow) && - ((xevent->xany.type == GraphicsExpose) || - (xevent->xany.type == NoExpose))) - return True; - else - return False; -} - -GdkEvent * -gdk_event_get_graphics_expose (GdkWindow *window) -{ - XEvent xevent; - GdkEvent *event; - - g_return_val_if_fail (window != NULL, NULL); - - XIfEvent (gdk_display, &xevent, graphics_expose_predicate, (XPointer)window); - - if (xevent.xany.type == GraphicsExpose) - { - event = gdk_event_new (); - - if (gdk_event_translate (event, &xevent)) - return event; - else - gdk_event_free (event); - } - - return NULL; -} - -/************************ - * Exposure compression * - ************************/ - -/* - * The following implements simple exposure compression. It is - * modelled after the way Xt does exposure compression - in - * particular compress_expose = XtExposeCompressMultiple. - * It compress consecutive sequences of exposure events, - * but not sequences that cross other events. (This is because - * if it crosses a ConfigureNotify, we could screw up and - * mistakenly compress the exposures generated for the new - * size - could we just check for ConfigureNotify?) - * - * Xt compresses to a region / bounding rectangle, we compress - * to two rectangles, and try find the two rectangles of minimal - * area for this - this is supposed to handle the typical - * L-shaped regions generated by OpaqueMove. - */ - -/* Given three rectangles, find the two rectangles that cover - * them with the smallest area. - */ -static void -gdk_add_rect_to_rects (GdkRectangle *rect1, - GdkRectangle *rect2, - GdkRectangle *new_rect) -{ - GdkRectangle t1, t2, t3; - gint size1, size2, size3; - - gdk_rectangle_union (rect1, rect2, &t1); - gdk_rectangle_union (rect1, new_rect, &t2); - gdk_rectangle_union (rect2, new_rect, &t3); - - size1 = t1.width * t1.height + new_rect->width * new_rect->height; - size2 = t2.width * t2.height + rect2->width * rect2->height; - size3 = t1.width * t1.height + rect1->width * rect1->height; - - if (size1 < size2) - { - if (size1 < size3) - { - *rect1 = t1; - *rect2 = *new_rect; - } - else - *rect2 = t3; - } - else - { - if (size2 < size3) - *rect1 = t2; - else - *rect2 = t3; - } -} - -typedef struct _GdkExposeInfo GdkExposeInfo; - -struct _GdkExposeInfo { - Window window; - gboolean seen_nonmatching; -}; - -Bool -expose_predicate (Display *display, XEvent *xevent, XPointer arg) -{ - GdkExposeInfo *info = (GdkExposeInfo *)arg; - - if (xevent->xany.type != Expose) - { - info->seen_nonmatching = TRUE; - } - - if (info->seen_nonmatching || (xevent->xany.window != info->window)) - return FALSE; - else - return TRUE; -} - -void -gdk_compress_exposures (XEvent *xevent, GdkWindow *window) -{ - gint nrects = 1; - gint count = 0; - GdkRectangle rect1; - GdkRectangle rect2; - GdkRectangle tmp_rect; - XEvent tmp_event; - GdkFilterReturn result; - GdkExposeInfo info; - GdkEvent event; - - info.window = xevent->xany.window; - info.seen_nonmatching = FALSE; - - rect1.x = xevent->xexpose.x; - rect1.y = xevent->xexpose.y; - rect1.width = xevent->xexpose.width; - rect1.height = xevent->xexpose.height; - - while (1) - { - if (count == 0) - { - if (!XCheckIfEvent (gdk_display, - &tmp_event, - expose_predicate, - (XPointer)&info)) - break; - } - else - XIfEvent (gdk_display, - &tmp_event, - expose_predicate, - (XPointer)&info); - - /* We apply filters here, and if it was filtered, completely - * ignore the return - */ - result = gdk_event_apply_filters (xevent, &event, - window ? - ((GdkWindowPrivate *)window)->filters - : gdk_default_filters); - - if (result != GDK_FILTER_CONTINUE) - { - if (result == GDK_FILTER_TRANSLATE) - gdk_event_put (&event); - continue; - } - - if (nrects == 1) - { - rect2.x = tmp_event.xexpose.x; - rect2.y = tmp_event.xexpose.y; - rect2.width = tmp_event.xexpose.width; - rect2.height = tmp_event.xexpose.height; - - nrects++; - } - else - { - tmp_rect.x = tmp_event.xexpose.x; - tmp_rect.y = tmp_event.xexpose.y; - tmp_rect.width = tmp_event.xexpose.width; - tmp_rect.height = tmp_event.xexpose.height; - - gdk_add_rect_to_rects (&rect1, &rect2, &tmp_rect); - } - - count = tmp_event.xexpose.count; - } - - if (nrects == 2) - { - gdk_rectangle_union (&rect1, &rect2, &tmp_rect); - - if ((tmp_rect.width * tmp_rect.height) < - 2 * (rect1.height * rect1.width + - rect2.height * rect2.width)) - { - rect1 = tmp_rect; - nrects = 1; - } - } - - if (nrects == 2) - { - event.expose.type = GDK_EXPOSE; - event.expose.window = window; - event.expose.area.x = rect2.x; - event.expose.area.y = rect2.y; - event.expose.area.width = rect2.width; - event.expose.area.height = rect2.height; - event.expose.count = 0; - - gdk_event_put (&event); - } - - xevent->xexpose.count = nrects - 1; - xevent->xexpose.x = rect1.x; - xevent->xexpose.y = rect1.y; - xevent->xexpose.width = rect1.width; - xevent->xexpose.height = rect1.height; -} - -/* - *-------------------------------------------------------------- - * gdk_event_get - * - * Gets the next event. - * - * Arguments: - * - * Results: - * If an event was received that we care about, returns - * a pointer to that event, to be freed with gdk_event_free. - * Otherwise, returns NULL. This function will also return - * before an event is received if the timeout interval - * runs out. - * - * Side effects: - * - *-------------------------------------------------------------- - */ - -GdkEvent * -gdk_event_get (void) -{ - GdkEvent *event; - GList *temp_list; - XEvent xevent; - -#if 0 - if (pred) - { - temp_list = putback_events; - while (temp_list) - { - temp_event = temp_list->data; - - if ((* pred) (temp_event, data)) - { - if (event) - *event = *temp_event; - putback_events = g_list_remove_link (putback_events, temp_list); - g_list_free (temp_list); - return TRUE; - } - - temp_list = temp_list->next; - } - - event_pred.func = pred; - event_pred.data = data; - - if (XCheckIfEvent (gdk_display, &xevent, gdk_event_get_type, (XPointer) & event_pred)) - if (event) - return gdk_event_translate (event, &xevent); - } - else -#endif - if (putback_events) - { - event = putback_events->data; - - temp_list = putback_events; - putback_events = g_list_remove_link (putback_events, temp_list); - g_list_free_1 (temp_list); - - return event; - } - - /* Wait for an event to occur or the timeout to elapse. - * If an event occurs "gdk_event_wait" will return TRUE. - * If the timeout elapses "gdk_event_wait" will return - * FALSE. - */ - if (gdk_event_wait ()) - { - /* If we get here we can rest assurred that an event - * has occurred. Read it. - */ -#ifdef USE_XIM - Window w = None; - - XNextEvent (gdk_display, &xevent); - if (gdk_xim_window) - switch (xevent.type) - { - case KeyPress: - case KeyRelease: - case ButtonPress: - case ButtonRelease: - w = GDK_WINDOW_XWINDOW (gdk_xim_window); - break; - } - - if (XFilterEvent (&xevent, w)) - return NULL; -#else - XNextEvent (gdk_display, &xevent); -#endif - - event = gdk_event_new (); - - event->any.type = GDK_NOTHING; - event->any.window = NULL; - event->any.send_event = FALSE; - event->any.send_event = xevent.xany.send_event; - - if (gdk_event_translate (event, &xevent)) - return event; - else - gdk_event_free (event); - } - - return NULL; -} - -void -gdk_event_put (GdkEvent *event) -{ - GdkEvent *new_event; - - g_return_if_fail (event != NULL); - - new_event = gdk_event_copy (event); - - putback_events = g_list_prepend (putback_events, new_event); -} - -/* - *-------------------------------------------------------------- - * gdk_event_copy - * - * Copy a event structure into new storage. - * - * Arguments: - * "event" is the event struct to copy. - * - * Results: - * A new event structure. Free it with gdk_event_free. - * - * Side effects: - * The reference count of the window in the event is increased. - * - *-------------------------------------------------------------- - */ - -static GMemChunk *event_chunk; - -static GdkEvent* -gdk_event_new (void) -{ - GdkEvent *new_event; - - if (event_chunk == NULL) - event_chunk = g_mem_chunk_new ("events", - sizeof (GdkEvent), - 4096, - G_ALLOC_AND_FREE); - - new_event = g_chunk_new (GdkEvent, event_chunk); - - return new_event; -} - -GdkEvent* -gdk_event_copy (GdkEvent *event) -{ - GdkEvent *new_event; - - g_return_val_if_fail (event != NULL, NULL); - - new_event = gdk_event_new (); - - *new_event = *event; - gdk_window_ref (new_event->any.window); - - switch (event->any.type) - { - case GDK_KEY_PRESS: - case GDK_KEY_RELEASE: - new_event->key.string = g_strdup (event->key.string); - break; - - case GDK_ENTER_NOTIFY: - case GDK_LEAVE_NOTIFY: - if (event->crossing.subwindow != NULL) - gdk_window_ref (event->crossing.subwindow); - break; - - case GDK_DRAG_ENTER: - case GDK_DRAG_LEAVE: - case GDK_DRAG_MOTION: - case GDK_DRAG_STATUS: - case GDK_DROP_START: - case GDK_DROP_FINISHED: - gdk_drag_context_ref (event->dnd.context); - break; - - - default: - break; - } - - return new_event; -} - -/* - *-------------------------------------------------------------- - * gdk_event_free - * - * Free a event structure obtained from gdk_event_copy. Do not use - * with other event structures. - * - * Arguments: - * "event" is the event struct to free. - * - * Results: - * - * Side effects: - * The reference count of the window in the event is decreased and - * might be freed, too. - * - *-------------------------------------------------------------- */ - -void -gdk_event_free (GdkEvent *event) -{ - g_assert (event_chunk != NULL); - g_return_if_fail (event != NULL); - - if (event->any.window) - gdk_window_unref (event->any.window); - - switch (event->any.type) - { - case GDK_KEY_PRESS: - case GDK_KEY_RELEASE: - g_free (event->key.string); - break; - - case GDK_ENTER_NOTIFY: - case GDK_LEAVE_NOTIFY: - if (event->crossing.subwindow != NULL) - gdk_window_unref (event->crossing.subwindow); - break; - - case GDK_DRAG_ENTER: - case GDK_DRAG_LEAVE: - case GDK_DRAG_MOTION: - case GDK_DRAG_STATUS: - case GDK_DROP_START: - case GDK_DROP_FINISHED: - gdk_drag_context_unref (event->dnd.context); - break; - - - default: - break; - } - - g_mem_chunk_free (event_chunk, event); -} - -/* - *-------------------------------------------------------------- - * gdk_set_show_events - * - * Turns on/off the showing of events. - * - * Arguments: - * "show_events" is a boolean describing whether or - * not to show the events gdk receives. - * - * Results: - * - * Side effects: - * When "show_events" is TRUE, calls to "gdk_event_get" - * will output debugging informatin regarding the event - * received to stdout. - * - *-------------------------------------------------------------- - */ - -/* - *-------------------------------------------------------------- - * gdk_event_get_time: - * Get the timestamp from an event. - * arguments: - * event: - * results: - * The event's time stamp, if it has one, otherwise - * GDK_CURRENT_TIME. - *-------------------------------------------------------------- - */ - -guint32 -gdk_event_get_time (GdkEvent *event) -{ - if (event) - switch (event->type) - { - case GDK_MOTION_NOTIFY: - return event->motion.time; - case GDK_BUTTON_PRESS: - case GDK_2BUTTON_PRESS: - case GDK_3BUTTON_PRESS: - case GDK_BUTTON_RELEASE: - return event->button.time; - case GDK_KEY_PRESS: - case GDK_KEY_RELEASE: - return event->key.time; - case GDK_ENTER_NOTIFY: - case GDK_LEAVE_NOTIFY: - return event->crossing.time; - case GDK_PROPERTY_NOTIFY: - return event->property.time; - case GDK_SELECTION_CLEAR: - case GDK_SELECTION_REQUEST: - case GDK_SELECTION_NOTIFY: - return event->selection.time; - case GDK_PROXIMITY_IN: - case GDK_PROXIMITY_OUT: - return event->proximity.time; - case GDK_DRAG_ENTER: - case GDK_DRAG_LEAVE: - case GDK_DRAG_MOTION: - case GDK_DRAG_STATUS: - case GDK_DROP_START: - case GDK_DROP_FINISHED: - return event->dnd.time; - default: /* use current time */ - break; - } - - return GDK_CURRENT_TIME; -} - -void -gdk_set_show_events (int show_events) -{ - if (show_events) - gdk_debug_flags |= GDK_DEBUG_EVENTS; - else - gdk_debug_flags &= ~GDK_DEBUG_EVENTS; -} - void gdk_set_use_xshm (gint use_xshm) { @@ -1220,12 +485,6 @@ gdk_set_use_xshm (gint use_xshm) } gint -gdk_get_show_events (void) -{ - return gdk_debug_flags & GDK_DEBUG_EVENTS; -} - -gint gdk_get_use_xshm (void) { return gdk_use_xshm; @@ -1337,89 +596,6 @@ gdk_timer_disable (void) timerp = NULL; } -gint -gdk_input_add_full (gint source, - GdkInputCondition condition, - GdkInputFunction function, - gpointer data, - GdkDestroyNotify destroy) -{ - static gint next_tag = 1; - GList *list; - GdkInput *input; - gint tag; - - tag = 0; - list = inputs; - - while (list) - { - input = list->data; - list = list->next; - - if ((input->source == source) && (input->condition == condition)) - { - if (input->destroy) - (input->destroy) (input->data); - input->function = function; - input->data = data; - input->destroy = destroy; - tag = input->tag; - } - } - - if (!tag) - { - input = g_new (GdkInput, 1); - input->tag = next_tag++; - input->source = source; - input->condition = condition; - input->function = function; - input->data = data; - input->destroy = destroy; - tag = input->tag; - - inputs = g_list_prepend (inputs, input); - } - - return tag; -} - -gint -gdk_input_add (gint source, - GdkInputCondition condition, - GdkInputFunction function, - gpointer data) -{ - return gdk_input_add_interp (source, condition, function, data, NULL); -} - -void -gdk_input_remove (gint tag) -{ - GList *list; - GdkInput *input; - - list = inputs; - while (list) - { - input = list->data; - - if (input->tag == tag) - { - if (input->destroy) - (input->destroy) (input->data); - - input->tag = 0; /* do not free it here */ - input->condition = 0; /* it's done in gdk_event_wait */ - - break; - } - - list = list->next; - } -} - /* *-------------------------------------------------------------- * gdk_pointer_grab @@ -1452,9 +628,6 @@ gdk_pointer_grab (GdkWindow * window, guint32 time) { /* From gdkwindow.c */ - extern const int nevent_masks; - extern const int event_mask_table[]; - gint return_val; GdkWindowPrivate *window_private; GdkWindowPrivate *confine_to_private; @@ -1485,10 +658,10 @@ gdk_pointer_grab (GdkWindow * window, xevent_mask = 0; - for (i = 0; i < nevent_masks; i++) + for (i = 0; i < gdk_nevent_masks; i++) { if (event_mask & (1 << (i + 1))) - xevent_mask |= event_mask_table[i]; + xevent_mask |= gdk_event_mask_table[i]; } if (gdk_input_vtable.grab_pointer) @@ -1516,7 +689,7 @@ gdk_pointer_grab (GdkWindow * window, } if (return_val == GrabSuccess) - xgrab_window = window_private; + gdk_xgrab_window = window_private; return return_val; } @@ -1543,7 +716,7 @@ gdk_pointer_ungrab (guint32 time) gdk_input_vtable.ungrab_pointer (time); XUngrabPointer (gdk_display, time); - xgrab_window = NULL; + gdk_xgrab_window = NULL; } /* @@ -1564,7 +737,7 @@ gdk_pointer_ungrab (guint32 time) gint gdk_pointer_is_grabbed (void) { - return xgrab_window != NULL; + return gdk_xgrab_window != NULL; } /* @@ -1747,1240 +920,12 @@ gdk_key_repeat_restore (void) } -/* - *-------------------------------------------------------------- - * gdk_flush - * - * Flushes the Xlib output buffer and then waits - * until all requests have been received and processed - * by the X server. The only real use for this function - * is in dealing with XShm. - * - * Arguments: - * - * Results: - * - * Side effects: - * - *-------------------------------------------------------------- - */ - -void gdk_flush (void) -{ - XSync (gdk_display, False); -} - - void gdk_beep (void) { XBell(gdk_display, 100); } - -/* - *-------------------------------------------------------------- - * gdk_event_wait - * - * Waits until an event occurs or the timer runs out. - * - * Arguments: - * - * Results: - * Returns TRUE if an event is ready to be read and FALSE - * if the timer ran out. - * - * Side effects: - * - *-------------------------------------------------------------- - */ - -static gint -gdk_event_wait (void) -{ - GList *list; - GList *temp_list; - GdkInput *input; - GdkInputCondition condition; - SELECT_MASK readfds; - SELECT_MASK writefds; - SELECT_MASK exceptfds; - int max_input; - int nfd; - - /* If there are no events pending we will wait for an event. - * The time we wait is dependant on the "timer". If no timer - * has been specified then we'll block until an event arrives. - * If a timer has been specified we'll block until an event - * arrives or the timer expires. (This is all done using the - * "select" system call). - */ - - if (XPending (gdk_display) == 0) - { - FD_ZERO (&readfds); - FD_ZERO (&writefds); - FD_ZERO (&exceptfds); - - FD_SET (connection_number, &readfds); - max_input = connection_number; - - list = inputs; - while (list) - { - input = list->data; - - if (input->tag) - { - if (input->condition & GDK_INPUT_READ) - FD_SET (input->source, &readfds); - if (input->condition & GDK_INPUT_WRITE) - FD_SET (input->source, &writefds); - if (input->condition & GDK_INPUT_EXCEPTION) - FD_SET (input->source, &exceptfds); - - max_input = MAX (max_input, input->source); - list = list->next; - } - else /* free removed inputs */ - { - temp_list = list; - - if (list->next) - list->next->prev = list->prev; - if (list->prev) - list->prev->next = list->next; - if (inputs == list) - inputs = list->next; - - list = list->next; - - temp_list->next = NULL; - temp_list->prev = NULL; - - g_free (temp_list->data); - g_list_free (temp_list); - } - } - -#ifdef USE_PTHREADS - if (gdk_using_threads) - { - gdk_select_waiting = TRUE; - - FD_SET (gdk_threads_pipe[0], &readfds); - max_input = MAX (max_input, gdk_threads_pipe[0]); - gdk_threads_leave (); - } -#endif - - nfd = select (max_input+1, &readfds, &writefds, &exceptfds, timerp); - -#ifdef USE_PTHREADS - if (gdk_using_threads) - { - gchar c; - gdk_threads_enter (); - gdk_select_waiting = FALSE; - - if (FD_ISSET (gdk_threads_pipe[0], &readfds)) - read (gdk_threads_pipe[0], &c, 1); - } -#endif - - timerp = NULL; - timer_val = 0; - - if (nfd > 0) - { - if (FD_ISSET (connection_number, &readfds)) - { - if (XPending (gdk_display) == 0) - { - if (nfd == 1) - { - XNoOp (gdk_display); - XFlush (gdk_display); - } - return FALSE; - } - else - return TRUE; - } - - list = inputs; - while (list) - { - input = list->data; - list = list->next; - - condition = 0; - if (FD_ISSET (input->source, &readfds)) - condition |= GDK_INPUT_READ; - if (FD_ISSET (input->source, &writefds)) - condition |= GDK_INPUT_WRITE; - if (FD_ISSET (input->source, &exceptfds)) - condition |= GDK_INPUT_EXCEPTION; - - if (condition && input->function) - (* input->function) (input->data, input->source, condition); - } - } - } - else - return TRUE; - - return FALSE; -} - -static gint -gdk_event_apply_filters (XEvent *xevent, - GdkEvent *event, - GList *filters) -{ - GdkEventFilter *filter; - GList *tmp_list; - GdkFilterReturn result; - - tmp_list = filters; - - while (tmp_list) - { - filter = (GdkEventFilter *)tmp_list->data; - - result = (*filter->function)(xevent, event, filter->data); - if (result != GDK_FILTER_CONTINUE) - return result; - - tmp_list = tmp_list->next; - } - - return GDK_FILTER_CONTINUE; -} - -void -gdk_add_client_message_filter (GdkAtom message_type, - GdkFilterFunc func, - gpointer data) -{ - GdkClientFilter *filter = g_new (GdkClientFilter, 1); - - filter->type = message_type; - filter->function = func; - filter->data = data; - - client_filters = g_list_prepend (client_filters, filter); -} - -static gint -gdk_event_translate (GdkEvent *event, - XEvent *xevent) -{ - - GdkWindow *window; - GdkWindowPrivate *window_private; - static XComposeStatus compose; - KeySym keysym; - int charcount; -#ifdef USE_XIM - static gchar* buf = NULL; - static gint buf_len= 0; -#else - char buf[16]; -#endif - gint return_val; - - return_val = FALSE; - - /* Find the GdkWindow that this event occurred in. - * - * We handle events with window=None - * specially - they are generated by XFree86's XInput under - * some circumstances. - */ - - if ((xevent->xany.window == None) && - gdk_input_vtable.window_none_event) - { - return_val = gdk_input_vtable.window_none_event (event,xevent); - - if (return_val >= 0) /* was handled */ - return return_val; - else - return_val = FALSE; - } - - window = gdk_window_lookup (xevent->xany.window); - window_private = (GdkWindowPrivate *) window; - - if (window != NULL) - gdk_window_ref (window); - - event->any.window = window; - event->any.send_event = xevent->xany.send_event; - - if (window_private && window_private->destroyed) - { - if (xevent->type != DestroyNotify) - return FALSE; - } - else - { - /* Check for filters for this window */ - - GdkFilterReturn result; - -#ifdef USE_XIM - if (window == NULL && - xevent->type == KeyPress && - gdk_xim_window && - !((GdkWindowPrivate *) gdk_xim_window)->destroyed) - { - /* - * If user presses a key in Preedit or Status window, keypress event - * is sometimes sent to these windows. These windows are not managed - * by GDK, so we redirect KeyPress event to gdk_xim_window. - * - * If someone want to use the window whitch is not managed by GDK - * and want to get KeyPress event, he/she must register the filter - * function to gdk_default_filters to intercept the event. - */ - - window = gdk_xim_window; - window_private = (GdkWindowPrivate *) window; - gdk_window_ref (window); - event->any.window = window; - - GDK_NOTE (XIM, - g_message ("KeyPress event is redirected to gdk_xim_window: %#lx", - xevent->xany.window)); - } -#endif /* USE_XIM */ - - result = gdk_event_apply_filters (xevent, event, - window_private - ?window_private->filters - :gdk_default_filters); - - if (result != GDK_FILTER_CONTINUE) - return (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE; - } - - if (window == NULL) - g_message ("Got event for unknown window: %#lx\n", xevent->xany.window); - - /* We do a "manual" conversion of the XEvent to a - * GdkEvent. The structures are mostly the same so - * the conversion is fairly straightforward. We also - * optionally print debugging info regarding events - * received. - */ - - return_val = TRUE; - - switch (xevent->type) - { - case KeyPress: - /* Lookup the string corresponding to the given keysym. - */ -#ifdef USE_XIM - if (buf_len == 0) - { - buf_len = 128; - buf = g_new (gchar, buf_len); - } - keysym = GDK_VoidSymbol; - - if (gdk_xim_ic && gdk_xim_ic->xic) - { - Status status; - - /* Clear keyval. Depending on status, may not be set */ - charcount = XmbLookupString(gdk_xim_ic->xic, - &xevent->xkey, buf, buf_len-1, - &keysym, &status); - if (status == XBufferOverflow) - { /* retry */ - /* alloc adequate size of buffer */ - GDK_NOTE (XIM, - g_message("XIM: overflow (required %i)", charcount)); - - while (buf_len <= charcount) - buf_len *= 2; - buf = (gchar *) g_realloc (buf, buf_len); - - charcount = XmbLookupString (gdk_xim_ic->xic, - &xevent->xkey, buf, buf_len-1, - &keysym, &status); - } - if (status == XLookupNone) - { - return_val = FALSE; - break; - } - } - else - charcount = XLookupString (&xevent->xkey, buf, buf_len, - &keysym, &compose); -#else - charcount = XLookupString (&xevent->xkey, buf, 16, - &keysym, &compose); -#endif - event->key.keyval = keysym; - - if (charcount > 0 && buf[charcount-1] == '\0') - charcount --; - else - buf[charcount] = '\0'; - - /* Print debugging info. - */ -#ifdef G_ENABLE_DEBUG - if (gdk_debug_flags & GDK_DEBUG_EVENTS) - { - g_message ("key press:\twindow: %ld key: %12s %d", - xevent->xkey.window - base_id, - event->key.keyval ? XKeysymToString (event->key.keyval) : "(none)", - event->key.keyval); - if (charcount > 0) - g_message ("\t\tlength: %4d string: \"%s\"", - charcount, buf); - } -#endif /* G_ENABLE_DEBUG */ - - event->key.type = GDK_KEY_PRESS; - event->key.window = window; - event->key.time = xevent->xkey.time; - event->key.state = (GdkModifierType) xevent->xkey.state; - event->key.string = g_strdup (buf); - event->key.length = charcount; - - break; - - case KeyRelease: - /* Lookup the string corresponding to the given keysym. - */ -#ifdef USE_XIM - if (buf_len == 0) - { - buf_len = 128; - buf = g_new (gchar, buf_len); - } -#endif - keysym = GDK_VoidSymbol; - charcount = XLookupString (&xevent->xkey, buf, 16, - &keysym, &compose); - event->key.keyval = keysym; - - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_message ("key release:\t\twindow: %ld key: %12s %d", - xevent->xkey.window - base_id, - XKeysymToString (event->key.keyval), - event->key.keyval)); - - event->key.type = GDK_KEY_RELEASE; - event->key.window = window; - event->key.time = xevent->xkey.time; - event->key.state = (GdkModifierType) xevent->xkey.state; - event->key.length = 0; - event->key.string = NULL; - - break; - - case ButtonPress: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_message ("button press:\t\twindow: %ld x,y: %d %d button: %d", - xevent->xbutton.window - base_id, - xevent->xbutton.x, xevent->xbutton.y, - xevent->xbutton.button)); - - if (window_private && - (window_private->extension_events != 0) && - gdk_input_ignore_core) - { - return_val = FALSE; - break; - } - - event->button.type = GDK_BUTTON_PRESS; - event->button.window = window; - event->button.time = xevent->xbutton.time; - event->button.x = xevent->xbutton.x; - event->button.y = xevent->xbutton.y; - event->button.x_root = (gfloat)xevent->xbutton.x_root; - event->button.y_root = (gfloat)xevent->xbutton.y_root; - event->button.pressure = 0.5; - event->button.xtilt = 0; - event->button.ytilt = 0; - event->button.state = (GdkModifierType) xevent->xbutton.state; - event->button.button = xevent->xbutton.button; - event->button.source = GDK_SOURCE_MOUSE; - event->button.deviceid = GDK_CORE_POINTER; - - if ((event->button.time < (button_click_time[1] + TRIPLE_CLICK_TIME)) && - (event->button.window == button_window[1]) && - (event->button.button == button_number[1])) - { - gdk_synthesize_click (event, 3); - - button_click_time[1] = 0; - button_click_time[0] = 0; - button_window[1] = NULL; - button_window[0] = 0; - button_number[1] = -1; - button_number[0] = -1; - } - else if ((event->button.time < (button_click_time[0] + DOUBLE_CLICK_TIME)) && - (event->button.window == button_window[0]) && - (event->button.button == button_number[0])) - { - gdk_synthesize_click (event, 2); - - button_click_time[1] = button_click_time[0]; - button_click_time[0] = event->button.time; - button_window[1] = button_window[0]; - button_window[0] = event->button.window; - button_number[1] = button_number[0]; - button_number[0] = event->button.button; - } - else - { - button_click_time[1] = 0; - button_click_time[0] = event->button.time; - button_window[1] = NULL; - button_window[0] = event->button.window; - button_number[1] = -1; - button_number[0] = event->button.button; - } - - break; - - case ButtonRelease: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_message ("button release:\twindow: %ld x,y: %d %d button: %d", - xevent->xbutton.window - base_id, - xevent->xbutton.x, xevent->xbutton.y, - xevent->xbutton.button)); - - if (window_private && - (window_private->extension_events != 0) && - gdk_input_ignore_core) - { - return_val = FALSE; - break; - } - - event->button.type = GDK_BUTTON_RELEASE; - event->button.window = window; - event->button.time = xevent->xbutton.time; - event->button.x = xevent->xbutton.x; - event->button.y = xevent->xbutton.y; - event->button.x_root = (gfloat)xevent->xbutton.x_root; - event->button.y_root = (gfloat)xevent->xbutton.y_root; - event->button.pressure = 0.5; - event->button.xtilt = 0; - event->button.ytilt = 0; - event->button.state = (GdkModifierType) xevent->xbutton.state; - event->button.button = xevent->xbutton.button; - event->button.source = GDK_SOURCE_MOUSE; - event->button.deviceid = GDK_CORE_POINTER; - - break; - - case MotionNotify: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_message ("motion notify:\t\twindow: %ld x,y: %d %d hint: %s", - xevent->xmotion.window - base_id, - xevent->xmotion.x, xevent->xmotion.y, - (xevent->xmotion.is_hint) ? "true" : "false")); - - if (window_private && - (window_private->extension_events != 0) && - gdk_input_ignore_core) - { - return_val = FALSE; - break; - } - - event->motion.type = GDK_MOTION_NOTIFY; - event->motion.window = window; - event->motion.time = xevent->xmotion.time; - event->motion.x = xevent->xmotion.x; - event->motion.y = xevent->xmotion.y; - event->motion.x_root = (gfloat)xevent->xmotion.x_root; - event->motion.y_root = (gfloat)xevent->xmotion.y_root; - event->motion.pressure = 0.5; - event->motion.xtilt = 0; - event->motion.ytilt = 0; - event->motion.state = (GdkModifierType) xevent->xmotion.state; - event->motion.is_hint = xevent->xmotion.is_hint; - event->motion.source = GDK_SOURCE_MOUSE; - event->motion.deviceid = GDK_CORE_POINTER; - - break; - - case EnterNotify: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_message ("enter notify:\t\twindow: %ld detail: %d subwin: %ld", - xevent->xcrossing.window - base_id, - xevent->xcrossing.detail, - xevent->xcrossing.subwindow - base_id)); - - /* Tell XInput stuff about it if appropriate */ - if (window_private && - !window_private->destroyed && - (window_private->extension_events != 0) && - gdk_input_vtable.enter_event) - gdk_input_vtable.enter_event (&xevent->xcrossing, window); - - event->crossing.type = GDK_ENTER_NOTIFY; - event->crossing.window = window; - - /* If the subwindow field of the XEvent is non-NULL, then - * lookup the corresponding GdkWindow. - */ - if (xevent->xcrossing.subwindow != None) - event->crossing.subwindow = gdk_window_lookup (xevent->xcrossing.subwindow); - else - event->crossing.subwindow = NULL; - - event->crossing.time = xevent->xcrossing.time; - event->crossing.x = xevent->xcrossing.x; - event->crossing.y = xevent->xcrossing.y; - event->crossing.x_root = xevent->xcrossing.x_root; - event->crossing.y_root = xevent->xcrossing.y_root; - - /* Translate the crossing mode into Gdk terms. - */ - switch (xevent->xcrossing.mode) - { - case NotifyNormal: - event->crossing.mode = GDK_CROSSING_NORMAL; - break; - case NotifyGrab: - event->crossing.mode = GDK_CROSSING_GRAB; - break; - case NotifyUngrab: - event->crossing.mode = GDK_CROSSING_UNGRAB; - break; - }; - - /* Translate the crossing detail into Gdk terms. - */ - switch (xevent->xcrossing.detail) - { - case NotifyInferior: - event->crossing.detail = GDK_NOTIFY_INFERIOR; - break; - case NotifyAncestor: - event->crossing.detail = GDK_NOTIFY_ANCESTOR; - break; - case NotifyVirtual: - event->crossing.detail = GDK_NOTIFY_VIRTUAL; - break; - case NotifyNonlinear: - event->crossing.detail = GDK_NOTIFY_NONLINEAR; - break; - case NotifyNonlinearVirtual: - event->crossing.detail = GDK_NOTIFY_NONLINEAR_VIRTUAL; - break; - default: - event->crossing.detail = GDK_NOTIFY_UNKNOWN; - break; - } - - event->crossing.focus = xevent->xcrossing.focus; - event->crossing.state = xevent->xcrossing.state; - - break; - - case LeaveNotify: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_message ("leave notify:\t\twindow: %ld detail: %d subwin: %ld", - xevent->xcrossing.window - base_id, - xevent->xcrossing.detail, xevent->xcrossing.subwindow - base_id)); - - event->crossing.type = GDK_LEAVE_NOTIFY; - event->crossing.window = window; - - /* If the subwindow field of the XEvent is non-NULL, then - * lookup the corresponding GdkWindow. - */ - if (xevent->xcrossing.subwindow != None) - event->crossing.subwindow = gdk_window_lookup (xevent->xcrossing.subwindow); - else - event->crossing.subwindow = NULL; - - event->crossing.time = xevent->xcrossing.time; - event->crossing.x = xevent->xcrossing.x; - event->crossing.y = xevent->xcrossing.y; - event->crossing.x_root = xevent->xcrossing.x_root; - event->crossing.y_root = xevent->xcrossing.y_root; - - /* Translate the crossing mode into Gdk terms. - */ - switch (xevent->xcrossing.mode) - { - case NotifyNormal: - event->crossing.mode = GDK_CROSSING_NORMAL; - break; - case NotifyGrab: - event->crossing.mode = GDK_CROSSING_GRAB; - break; - case NotifyUngrab: - event->crossing.mode = GDK_CROSSING_UNGRAB; - break; - }; - - /* Translate the crossing detail into Gdk terms. - */ - switch (xevent->xcrossing.detail) - { - case NotifyInferior: - event->crossing.detail = GDK_NOTIFY_INFERIOR; - break; - case NotifyAncestor: - event->crossing.detail = GDK_NOTIFY_ANCESTOR; - break; - case NotifyVirtual: - event->crossing.detail = GDK_NOTIFY_VIRTUAL; - break; - case NotifyNonlinear: - event->crossing.detail = GDK_NOTIFY_NONLINEAR; - break; - case NotifyNonlinearVirtual: - event->crossing.detail = GDK_NOTIFY_NONLINEAR_VIRTUAL; - break; - default: - event->crossing.detail = GDK_NOTIFY_UNKNOWN; - break; - } - - event->crossing.focus = xevent->xcrossing.focus; - event->crossing.state = xevent->xcrossing.state; - - break; - - case FocusIn: - case FocusOut: - /* We only care about focus events that indicate that _this_ - * window (not a ancestor or child) got or lost the focus - */ - switch (xevent->xfocus.detail) - { - case NotifyAncestor: - case NotifyInferior: - case NotifyNonlinear: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_message ("focus %s:\t\twindow: %ld", - (xevent->xany.type == FocusIn) ? "in" : "out", - xevent->xfocus.window - base_id)); - - /* gdk_keyboard_grab() causes following events. These events confuse - * the XIM focus, so ignore them. - */ - if (xevent->xfocus.mode == NotifyGrab || - xevent->xfocus.mode == NotifyUngrab) - break; - - event->focus_change.type = GDK_FOCUS_CHANGE; - event->focus_change.window = window; - event->focus_change.in = (xevent->xany.type == FocusIn); - - break; - default: - return_val = FALSE; - } - break; - - case KeymapNotify: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_message ("keymap notify")); - - /* Not currently handled */ - return_val = FALSE; - break; - - case Expose: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_message ("expose:\t\twindow: %ld %d x,y: %d %d w,h: %d %d", - xevent->xexpose.window - base_id, xevent->xexpose.count, - xevent->xexpose.x, xevent->xexpose.y, - xevent->xexpose.width, xevent->xexpose.height)); - gdk_compress_exposures (xevent, window); - - event->expose.type = GDK_EXPOSE; - event->expose.window = window; - event->expose.area.x = xevent->xexpose.x; - event->expose.area.y = xevent->xexpose.y; - event->expose.area.width = xevent->xexpose.width; - event->expose.area.height = xevent->xexpose.height; - event->expose.count = xevent->xexpose.count; - - break; - - case GraphicsExpose: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_message ("graphics expose:\tdrawable: %ld", - xevent->xgraphicsexpose.drawable - base_id)); - - event->expose.type = GDK_EXPOSE; - event->expose.window = window; - event->expose.area.x = xevent->xgraphicsexpose.x; - event->expose.area.y = xevent->xgraphicsexpose.y; - event->expose.area.width = xevent->xgraphicsexpose.width; - event->expose.area.height = xevent->xgraphicsexpose.height; - event->expose.count = xevent->xexpose.count; - - break; - - case NoExpose: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_message ("no expose:\t\tdrawable: %ld", - xevent->xnoexpose.drawable - base_id)); - - event->no_expose.type = GDK_NO_EXPOSE; - event->no_expose.window = window; - - break; - - case VisibilityNotify: - /* Print debugging info. - */ -#ifdef G_ENABLE_DEBUG - if (gdk_debug_flags & GDK_DEBUG_EVENTS) - switch (xevent->xvisibility.state) - { - case VisibilityFullyObscured: - g_message ("visibility notify:\twindow: %ld none", - xevent->xvisibility.window - base_id); - break; - case VisibilityPartiallyObscured: - g_message ("visibility notify:\twindow: %ld partial", - xevent->xvisibility.window - base_id); - break; - case VisibilityUnobscured: - g_message ("visibility notify:\twindow: %ld full", - xevent->xvisibility.window - base_id); - break; - } -#endif /* G_ENABLE_DEBUG */ - - event->visibility.type = GDK_VISIBILITY_NOTIFY; - event->visibility.window = window; - - switch (xevent->xvisibility.state) - { - case VisibilityFullyObscured: - event->visibility.state = GDK_VISIBILITY_FULLY_OBSCURED; - break; - - case VisibilityPartiallyObscured: - event->visibility.state = GDK_VISIBILITY_PARTIAL; - break; - - case VisibilityUnobscured: - event->visibility.state = GDK_VISIBILITY_UNOBSCURED; - break; - } - - break; - - case CreateNotify: - /* Not currently handled */ - break; - - case DestroyNotify: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_message ("destroy notify:\twindow: %ld", - xevent->xdestroywindow.window - base_id)); - - event->any.type = GDK_DESTROY; - event->any.window = window; - - return_val = window_private && !window_private->destroyed; - - if(window && window_private->xwindow != GDK_ROOT_WINDOW()) - gdk_window_destroy_notify (window); - break; - - case UnmapNotify: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_message ("unmap notify:\t\twindow: %ld", - xevent->xmap.window - base_id)); - - event->any.type = GDK_UNMAP; - event->any.window = window; - - if (xgrab_window == window_private) - xgrab_window = NULL; - - break; - - case MapNotify: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_message ("map notify:\t\twindow: %ld", - xevent->xmap.window - base_id)); - - event->any.type = GDK_MAP; - event->any.window = window; - - break; - - case ReparentNotify: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_message ("reparent notify:\twindow: %ld", - xevent->xreparent.window - base_id)); - - /* Not currently handled */ - return_val = FALSE; - break; - - case ConfigureNotify: - /* Print debugging info. - */ - while ((XPending (gdk_display) > 0) && - XCheckTypedWindowEvent(gdk_display, xevent->xany.window, - ConfigureNotify, xevent)) - { - GdkFilterReturn result; - - GDK_NOTE (EVENTS, - g_message ("configure notify discarded:\twindow: %ld", - xevent->xconfigure.window - base_id)); - - result = gdk_event_apply_filters (xevent, event, - window_private - ?window_private->filters - :gdk_default_filters); - - /* If the result is GDK_FILTER_REMOVE, there will be - * trouble, but anybody who filtering the Configure events - * better know what they are doing - */ - if (result != GDK_FILTER_CONTINUE) - { - return (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE; - } - - /*XSync (gdk_display, 0);*/ - } - - - GDK_NOTE (EVENTS, - g_message ("configure notify:\twindow: %ld x,y: %d %d w,h: %d %d b-w: %d above: %ld ovr: %d", - xevent->xconfigure.window - base_id, - xevent->xconfigure.x, - xevent->xconfigure.y, - xevent->xconfigure.width, - xevent->xconfigure.height, - xevent->xconfigure.border_width, - xevent->xconfigure.above - base_id, - xevent->xconfigure.override_redirect)); - - if (!window_private->destroyed && - (window_private->extension_events != 0) && - gdk_input_vtable.configure_event) - gdk_input_vtable.configure_event (&xevent->xconfigure, window); - - if (window_private->window_type == GDK_WINDOW_CHILD) - return_val = FALSE; - else - { - event->configure.type = GDK_CONFIGURE; - event->configure.window = window; - event->configure.width = xevent->xconfigure.width; - event->configure.height = xevent->xconfigure.height; - - if (!xevent->xconfigure.x && - !xevent->xconfigure.y && - !window_private->destroyed) - { - gint tx = 0; - gint ty = 0; - Window child_window = 0; - - if (!XTranslateCoordinates (window_private->xdisplay, - window_private->xwindow, - gdk_root_window, - 0, 0, - &tx, &ty, - &child_window)) - g_warning ("GdkWindow %ld doesn't share root windows display?", - window_private->xwindow - base_id); - event->configure.x = tx; - event->configure.y = ty; - } - else - { - event->configure.x = xevent->xconfigure.x; - event->configure.y = xevent->xconfigure.y; - } - window_private->x = event->configure.x; - window_private->y = event->configure.y; - window_private->width = xevent->xconfigure.width; - window_private->height = xevent->xconfigure.height; - if (window_private->resize_count > 1) - window_private->resize_count -= 1; - } - break; - - case PropertyNotify: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_message ("property notify:\twindow: %ld", - xevent->xproperty.window - base_id)); - - event->property.type = GDK_PROPERTY_NOTIFY; - event->property.window = window; - event->property.atom = xevent->xproperty.atom; - event->property.time = xevent->xproperty.time; - event->property.state = xevent->xproperty.state; - - break; - - case SelectionClear: - GDK_NOTE (EVENTS, - g_message ("selection clear:\twindow: %ld", - xevent->xproperty.window - base_id)); - - event->selection.type = GDK_SELECTION_CLEAR; - event->selection.window = window; - event->selection.selection = xevent->xselectionclear.selection; - event->selection.time = xevent->xselectionclear.time; - - break; - - case SelectionRequest: - GDK_NOTE (EVENTS, - g_message ("selection request:\twindow: %ld", - xevent->xproperty.window - base_id)); - - event->selection.type = GDK_SELECTION_REQUEST; - event->selection.window = window; - event->selection.selection = xevent->xselectionrequest.selection; - event->selection.target = xevent->xselectionrequest.target; - event->selection.property = xevent->xselectionrequest.property; - event->selection.requestor = xevent->xselectionrequest.requestor; - event->selection.time = xevent->xselectionrequest.time; - - break; - - case SelectionNotify: - GDK_NOTE (EVENTS, - g_message ("selection notify:\twindow: %ld", - xevent->xproperty.window - base_id)); - - - event->selection.type = GDK_SELECTION_NOTIFY; - event->selection.window = window; - event->selection.selection = xevent->xselection.selection; - event->selection.target = xevent->xselection.target; - event->selection.property = xevent->xselection.property; - event->selection.time = xevent->xselection.time; - - break; - - case ColormapNotify: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_message ("colormap notify:\twindow: %ld", - xevent->xcolormap.window - base_id)); - - /* Not currently handled */ - return_val = FALSE; - break; - - case ClientMessage: - { - GList *tmp_list; - GdkFilterReturn result = GDK_FILTER_CONTINUE; - - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_message ("client message:\twindow: %ld", - xevent->xclient.window - base_id)); - - tmp_list = client_filters; - while (tmp_list) - { - GdkClientFilter *filter = tmp_list->data; - if (filter->type == xevent->xclient.message_type) - { - result = (*filter->function) (xevent, event, filter->data); - break; - } - - tmp_list = tmp_list->next; - } - - switch (result) - { - case GDK_FILTER_REMOVE: - return_val = FALSE; - break; - case GDK_FILTER_TRANSLATE: - return_val = TRUE; - break; - case GDK_FILTER_CONTINUE: - /* Send unknown ClientMessage's on to Gtk for it to use */ - event->client.type = GDK_CLIENT_EVENT; - event->client.window = window; - event->client.message_type = xevent->xclient.message_type; - event->client.data_format = xevent->xclient.format; - memcpy(&event->client.data, &xevent->xclient.data, - sizeof(event->client.data)); - } - } - - break; - - case MappingNotify: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_message ("mapping notify")); - - /* Let XLib know that there is a new keyboard mapping. - */ - XRefreshKeyboardMapping (&xevent->xmapping); - return_val = FALSE; - break; - - default: - /* something else - (e.g., a Xinput event) */ - - if (window_private && - !window_private->destroyed && - (window_private->extension_events != 0) && - gdk_input_vtable.other_event) - return_val = gdk_input_vtable.other_event(event, xevent, window); - else - return_val = FALSE; - - break; - } - - if (return_val) - { - if (event->any.window) - gdk_window_ref (event->any.window); - if (((event->any.type == GDK_ENTER_NOTIFY) || - (event->any.type == GDK_LEAVE_NOTIFY)) && - (event->crossing.subwindow != NULL)) - gdk_window_ref (event->crossing.subwindow); - } - else - { - /* Mark this event as having no resources to be freed */ - event->any.window = NULL; - event->any.type = GDK_NOTHING; - } - - if (window) - gdk_window_unref (window); - - return return_val; -} - -GdkFilterReturn -gdk_wm_protocols_filter (GdkXEvent *xev, - GdkEvent *event, - gpointer data) -{ - XEvent *xevent = (XEvent *)xev; - - if ((Atom) xevent->xclient.data.l[0] == gdk_wm_delete_window) - { - /* The delete window request specifies a window - * to delete. We don't actually destroy the - * window because "it is only a request". (The - * window might contain vital data that the - * program does not want destroyed). Instead - * the event is passed along to the program, - * which should then destroy the window. - */ - GDK_NOTE (EVENTS, - g_message ("delete window:\t\twindow: %ld", - xevent->xclient.window - base_id)); - - event->any.type = GDK_DELETE; - - return GDK_FILTER_TRANSLATE; - } - else if ((Atom) xevent->xclient.data.l[0] == gdk_wm_take_focus) - { - } - - return GDK_FILTER_REMOVE; -} - -#if 0 -static Bool -gdk_event_get_type (Display *display, - XEvent *xevent, - XPointer arg) -{ - GdkEvent event; - GdkPredicate *pred; - - if (gdk_event_translate (&event, xevent)) - { - pred = (GdkPredicate*) arg; - return (* pred->func) (&event, pred->data); - } - - return FALSE; -} -#endif - -static void -gdk_synthesize_click (GdkEvent *event, - gint nclicks) -{ - GdkEvent temp_event; - - g_return_if_fail (event != NULL); - - temp_event = *event; - temp_event.type = (nclicks == 2) ? GDK_2BUTTON_PRESS : GDK_3BUTTON_PRESS; - - gdk_event_put (&temp_event); -} - /* *-------------------------------------------------------------- * gdk_exit_func @@ -3115,88 +1060,50 @@ gdk_event_send_client_message (GdkEvent *event, guint32 xid) return gdk_send_xevent (xid, False, NoEventMask, &sev); } -/* Sends a ClientMessage to all toplevel client windows */ -gboolean -gdk_event_send_client_message_to_all_recurse (XEvent *xev, - guint32 xid, - guint level) +static RETSIGTYPE +gdk_signal (int sig_num) { - static GdkAtom wm_state_atom = GDK_NONE; - - Atom type = None; - int format; - unsigned long nitems, after; - unsigned char *data; + static int caught_fatal_sig = 0; + char *sig; - Window *ret_children, ret_root, ret_parent; - unsigned int ret_nchildren; - int i; + if (caught_fatal_sig) + kill (getpid (), sig_num); + caught_fatal_sig = 1; - gboolean send = FALSE; - gboolean found = FALSE; - - if (!wm_state_atom) - wm_state_atom = gdk_atom_intern ("WM_STATE", FALSE); - - gdk_error_code = 0; - XGetWindowProperty (gdk_display, xid, wm_state_atom, 0, 0, False, AnyPropertyType, - &type, &format, &nitems, &after, &data); - - if (gdk_error_code) - { - gdk_error_code = 0; - return FALSE; - } - - if (type) - { - send = TRUE; - XFree (data); - } - else + switch (sig_num) { - /* OK, we're all set, now let's find some windows to send this to */ - if (XQueryTree(gdk_display, xid, &ret_root, &ret_parent, - &ret_children, &ret_nchildren) != True) - return FALSE; - - if (gdk_error_code) - return FALSE; - - for(i = 0; i < ret_nchildren; i++) - if (gdk_event_send_client_message_to_all_recurse(xev, ret_children[i], level + 1)) - found = TRUE; - - XFree(ret_children); - } - - if (send || (!found && (level == 1))) - { - xev->xclient.window = xid; - gdk_send_xevent (xid, False, NoEventMask, xev); + case SIGHUP: + sig = "sighup"; + break; + case SIGINT: + sig = "sigint"; + break; + case SIGQUIT: + sig = "sigquit"; + break; + case SIGBUS: + sig = "sigbus"; + break; + case SIGSEGV: + sig = "sigsegv"; + break; + case SIGPIPE: + sig = "sigpipe"; + break; + case SIGTERM: + sig = "sigterm"; + break; + default: + sig = "unknown signal"; + break; } - - return (send || found); -} - -void -gdk_event_send_clientmessage_toall (GdkEvent *event) -{ - XEvent sev; - gint old_warnings = gdk_error_warnings; - - g_return_if_fail(event != NULL); - /* Set up our event to send, with the exception of its target window */ - sev.xclient.type = ClientMessage; - sev.xclient.display = gdk_display; - sev.xclient.format = event->client.data_format; - memcpy(&sev.xclient.data, &event->client.data, sizeof(sev.xclient.data)); - sev.xclient.message_type = event->client.message_type; - - gdk_event_send_client_message_to_all_recurse(&sev, gdk_root_window, 0); - - gdk_error_warnings = old_warnings; + g_message ("\n** ERROR **: %s caught", sig); +#ifdef G_ENABLE_DEBUG + abort (); +#else /* !G_ENABLE_DEBUG */ + gdk_exit (1); +#endif /* !G_ENABLE_DEBUG */ } gchar * @@ -37,12 +37,16 @@ gchar* gdk_set_locale (void); gint gdk_events_pending (void); GdkEvent *gdk_event_get (void); GdkEvent *gdk_event_get_graphics_expose (GdkWindow *window); -void gdk_event_put (GdkEvent *event); +void gdk_event_put (GdkEvent *event); GdkEvent *gdk_event_copy (GdkEvent *event); void gdk_event_free (GdkEvent *event); guint32 gdk_event_get_time (GdkEvent *event); +void gdk_event_handler_set (GdkEventFunc func, + gpointer data, + GDestroyNotify notify); + void gdk_set_show_events (gint show_events); void gdk_set_use_xshm (gint use_xshm); @@ -933,18 +937,6 @@ GdkRegion* gdk_regions_subtract (GdkRegion *source1, GdkRegion* gdk_regions_xor (GdkRegion *source1, GdkRegion *source2); -/* Threads - */ - -gboolean gdk_threads_init (void); -void gdk_threads_enter (void); -void gdk_threads_leave (void); - -/* If the mainloop thread is in its select, wake it up. - * For GTK's idle handling - */ -void gdk_threads_wake (void); - /* Miscellaneous */ void gdk_event_send_clientmessage_toall (GdkEvent *event); gboolean gdk_event_send_client_message (GdkEvent *event, diff --git a/gdk/gdkglobals.c b/gdk/gdkglobals.c index eeebb51491..125fc9211b 100644 --- a/gdk/gdkglobals.c +++ b/gdk/gdkglobals.c @@ -54,6 +54,14 @@ gint gdk_error_warnings = TRUE; gint gdk_null_window_warnings = TRUE; GList *gdk_default_filters = NULL; +gboolean gdk_xim_using; /* using XIM Protocol if TRUE */ +GdkICPrivate *gdk_xim_ic; /* currently using IC */ +GdkWindow *gdk_xim_window; /* currently using Widow */ + +GdkWindowPrivate *gdk_xgrab_window = NULL; /* Window that currently holds the + * x pointer grab + */ + gboolean gdk_using_threads = FALSE; /* Used to signal the mainloop thread from its select() */ diff --git a/gdk/gdkim.c b/gdk/gdkim.c index b12aebd9d3..5b2ded3fd3 100644 --- a/gdk/gdkim.c +++ b/gdk/gdkim.c @@ -1235,8 +1235,6 @@ gdk_ic_get_events (GdkIC *ic) gint i; /* From gdkwindow.c */ - extern int nevent_masks; - extern int event_mask_table[]; g_return_val_if_fail (ic != NULL, 0); @@ -1252,11 +1250,11 @@ gdk_ic_get_events (GdkIC *ic) } mask = 0; - for (i=0, bit=2; i < nevent_masks; i++, bit <<= 1) - if (xmask & event_mask_table [i]) + for (i=0, bit=2; i < gdk_nevent_masks; i++, bit <<= 1) + if (xmask & gdk_event_mask_table [i]) { mask |= bit; - xmask &= ~ event_mask_table [i]; + xmask &= ~ gdk_event_mask_table [i]; } if (xmask) diff --git a/gdk/gdkprivate.h b/gdk/gdkprivate.h index 6131cb55ae..07ab6b45c0 100644 --- a/gdk/gdkprivate.h +++ b/gdk/gdkprivate.h @@ -218,6 +218,7 @@ typedef enum { GDK_DEBUG_XIM = 1 << 4 } GdkDebugFlag; +void gdk_events_init (void); void gdk_window_init (void); void gdk_visual_init (void); void gdk_dnd_init (void); @@ -276,6 +277,12 @@ extern gint gdk_error_warnings; extern gint gdk_null_window_warnings; extern GList *gdk_default_filters; extern gboolean gdk_using_threads; +extern const int gdk_nevent_masks; +extern const int gdk_event_mask_table[]; + +extern GdkWindowPrivate *gdk_xgrab_window; /* Window that currently holds the + * x pointer grab + */ /* Threading stuff */ #ifdef USE_PTHREADS diff --git a/gdk/gdkthreads.c b/gdk/gdkthreads.c deleted file mode 100644 index 3ede36b60e..0000000000 --- a/gdk/gdkthreads.c +++ /dev/null @@ -1,68 +0,0 @@ -/* GDK - The GIMP Drawing Kit - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * 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., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ -#include "config.h" -#include "gdk.h" -#include "gdkprivate.h" - -#ifdef USE_PTHREADS -#include <unistd.h> -#include <pthread.h> - -pthread_mutex_t gdk_threads_mutex = PTHREAD_MUTEX_INITIALIZER; -#endif /* USE_PTHREADS */ - -gboolean -gdk_threads_init (void) -{ -#ifdef USE_PTHREADS - pipe (gdk_threads_pipe); - gdk_using_threads = TRUE; - return TRUE; -#else - return FALSE; -#endif -} - -void -gdk_threads_enter (void) -{ -#ifdef USE_PTHREADS - pthread_mutex_lock (&gdk_threads_mutex); -#endif -} - -void -gdk_threads_leave (void) -{ -#ifdef USE_PTHREADS - pthread_mutex_unlock (&gdk_threads_mutex); -#endif -} - -void -gdk_threads_wake (void) -{ -#ifdef USE_PTHREADS - if (gdk_select_waiting) - { - gdk_select_waiting = FALSE; - write (gdk_threads_pipe[1], "A", 1); - } -#endif -} diff --git a/gdk/gdktypes.h b/gdk/gdktypes.h index 21aa123d1a..30088c405e 100644 --- a/gdk/gdktypes.h +++ b/gdk/gdktypes.h @@ -86,7 +86,7 @@ typedef struct _GdkDeviceKey GdkDeviceKey; typedef struct _GdkDeviceInfo GdkDeviceInfo; typedef struct _GdkTimeCoord GdkTimeCoord; typedef struct _GdkRegion GdkRegion; -typedef gint (*GdkEventFunc) (GdkEvent *event, +typedef void (*GdkEventFunc) (GdkEvent *event, gpointer data); typedef struct _GdkIC GdkIC; diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c index 72a56d8584..8e684c614e 100644 --- a/gdk/gdkwindow.c +++ b/gdk/gdkwindow.c @@ -33,7 +33,7 @@ #include <X11/extensions/shape.h> #endif -const int event_mask_table[20] = +const int gdk_event_mask_table[20] = { ExposureMask, PointerMotionMask, @@ -56,7 +56,7 @@ const int event_mask_table[20] = 0, /* PROXIMTY_OUT */ SubstructureNotifyMask }; -const int nevent_masks = sizeof(event_mask_table)/sizeof(int); +const int gdk_nevent_masks = sizeof(gdk_event_mask_table)/sizeof(int); static gboolean gdk_window_have_shape_ext (void); @@ -299,10 +299,10 @@ gdk_window_new (GdkWindow *parent, xvisual = ((GdkVisualPrivate*) visual)->xvisual; xattributes.event_mask = StructureNotifyMask; - for (i = 0; i < nevent_masks; i++) + for (i = 0; i < gdk_nevent_masks; i++) { if (attributes->event_mask & (1 << (i + 1))) - xattributes.event_mask |= event_mask_table[i]; + xattributes.event_mask |= gdk_event_mask_table[i]; } if (xattributes.event_mask) @@ -1703,9 +1703,9 @@ gdk_window_get_events (GdkWindow *window) &attrs); event_mask = 0; - for (i = 0; i < nevent_masks; i++) + for (i = 0; i < gdk_nevent_masks; i++) { - if (attrs.your_event_mask & event_mask_table[i]) + if (attrs.your_event_mask & gdk_event_mask_table[i]) event_mask |= 1 << (i + 1); } @@ -1727,10 +1727,10 @@ gdk_window_set_events (GdkWindow *window, return; xevent_mask = StructureNotifyMask; - for (i = 0; i < nevent_masks; i++) + for (i = 0; i < gdk_nevent_masks; i++) { if (event_mask & (1 << (i + 1))) - xevent_mask |= event_mask_table[i]; + xevent_mask |= gdk_event_mask_table[i]; } XSelectInput (gdk_display, private->xwindow, diff --git a/gdk/x11/gdkglobals-x11.c b/gdk/x11/gdkglobals-x11.c index eeebb51491..125fc9211b 100644 --- a/gdk/x11/gdkglobals-x11.c +++ b/gdk/x11/gdkglobals-x11.c @@ -54,6 +54,14 @@ gint gdk_error_warnings = TRUE; gint gdk_null_window_warnings = TRUE; GList *gdk_default_filters = NULL; +gboolean gdk_xim_using; /* using XIM Protocol if TRUE */ +GdkICPrivate *gdk_xim_ic; /* currently using IC */ +GdkWindow *gdk_xim_window; /* currently using Widow */ + +GdkWindowPrivate *gdk_xgrab_window = NULL; /* Window that currently holds the + * x pointer grab + */ + gboolean gdk_using_threads = FALSE; /* Used to signal the mainloop thread from its select() */ diff --git a/gdk/x11/gdkim-x11.c b/gdk/x11/gdkim-x11.c index b12aebd9d3..5b2ded3fd3 100644 --- a/gdk/x11/gdkim-x11.c +++ b/gdk/x11/gdkim-x11.c @@ -1235,8 +1235,6 @@ gdk_ic_get_events (GdkIC *ic) gint i; /* From gdkwindow.c */ - extern int nevent_masks; - extern int event_mask_table[]; g_return_val_if_fail (ic != NULL, 0); @@ -1252,11 +1250,11 @@ gdk_ic_get_events (GdkIC *ic) } mask = 0; - for (i=0, bit=2; i < nevent_masks; i++, bit <<= 1) - if (xmask & event_mask_table [i]) + for (i=0, bit=2; i < gdk_nevent_masks; i++, bit <<= 1) + if (xmask & gdk_event_mask_table [i]) { mask |= bit; - xmask &= ~ event_mask_table [i]; + xmask &= ~ gdk_event_mask_table [i]; } if (xmask) diff --git a/gdk/x11/gdkmain-x11.c b/gdk/x11/gdkmain-x11.c index 117f4534f8..efd926154b 100644 --- a/gdk/x11/gdkmain-x11.c +++ b/gdk/x11/gdkmain-x11.c @@ -39,48 +39,16 @@ #include "gdk.h" #include "gdkprivate.h" #include "gdkinput.h" -#include "gdki18n.h" #include "gdkx.h" -#include "gdkkeysyms.h" +#include "gdki18n.h" #ifndef X_GETTIMEOFDAY #define X_GETTIMEOFDAY(tv) gettimeofday (tv, NULL) #endif /* X_GETTIMEOFDAY */ -#define DOUBLE_CLICK_TIME 250 -#define TRIPLE_CLICK_TIME 500 -#define DOUBLE_CLICK_DIST 5 -#define TRIPLE_CLICK_DIST 5 - - -#ifndef NO_FD_SET -# define SELECT_MASK fd_set -#else -# ifndef _AIX -typedef long fd_mask; -# endif -# if defined(_IBMR2) -# define SELECT_MASK void -# else -# define SELECT_MASK int -# endif -#endif - - -typedef struct _GdkInput GdkInput; typedef struct _GdkPredicate GdkPredicate; -struct _GdkInput -{ - gint tag; - gint source; - GdkInputCondition condition; - GdkInputFunction function; - gpointer data; - GdkDestroyNotify destroy; -}; - struct _GdkPredicate { GdkEventFunc func; @@ -91,21 +59,6 @@ struct _GdkPredicate * Private function declarations */ -static GdkEvent *gdk_event_new (void); -static gint gdk_event_wait (void); -static gint gdk_event_apply_filters (XEvent *xevent, - GdkEvent *event, - GList *filters); -static gint gdk_event_translate (GdkEvent *event, - XEvent *xevent); -#if 0 -static Bool gdk_event_get_type (Display *display, - XEvent *xevent, - XPointer arg); -#endif -static void gdk_synthesize_click (GdkEvent *event, - gint nclicks); - #ifndef HAVE_XCONVERTCASE static void gdkx_XConvertCase (KeySym symbol, KeySym *lower, @@ -113,16 +66,6 @@ static void gdkx_XConvertCase (KeySym symbol, #define XConvertCase gdkx_XConvertCase #endif -/* - * old junk from offix, we might use it though so leave it - */ -Window gdk_get_client_window (Display *dpy, - Window win); -#ifdef WE_HAVE_MOTIF_DROPS_DONE -static GdkWindow * gdk_drop_get_real_window (GdkWindow *w, - guint16 *x, - guint16 *y); -#endif static void gdk_exit_func (void); static int gdk_x_error (Display *display, XErrorEvent *error); @@ -137,13 +80,6 @@ GdkFilterReturn gdk_wm_protocols_filter (GdkXEvent *xev, static int gdk_initialized = 0; /* 1 if the library is initialized, * 0 otherwise. */ -static int connection_number = 0; /* The file descriptor number of our - * connection to the X server. This - * is used so that we may determine - * when events are pending by using - * the "select" system call. - */ - static struct timeval start; /* The time at which the library was * last initialized. @@ -162,33 +98,7 @@ static struct timeval *timerp; /* The actual timer passed to "select" static guint32 timer_val; /* The timeout length as specified by * the user in milliseconds. */ -static GList *inputs; /* A list of the input file descriptors - * that we care about. Each list node - * contains a GdkInput struct that describes - * when we are interested in the specified - * file descriptor. That is, when it is - * available for read, write or has an - * exception pending. - */ -static guint32 button_click_time[2]; /* The last 2 button click times. Used - * to determine if the latest button click - * is part of a double or triple click. - */ -static GdkWindow *button_window[2]; /* The last 2 windows to receive button presses. - * Also used to determine if the latest button - * click is part of a double or triple click. - */ -static guint button_number[2]; /* The last 2 buttons to be pressed. - */ -static GdkWindowPrivate *xgrab_window = NULL; /* Window that currently holds the - * x pointer grab - */ -static GList *client_filters; /* Filters for client messages */ - -static GList *putback_events = NULL; - -static gulong base_id; static gint autorepeat; #ifdef G_ENABLE_DEBUG @@ -454,18 +364,6 @@ gdk_init (int *argc, exit(1); } - /* This is really crappy. We have to look into the display structure - * to find the base resource id. This is only needed for recording - * and playback of events. - */ - /* base_id = RESOURCE_BASE; */ - base_id = 0; - GDK_NOTE (EVENTS, g_message ("base id: %lu", base_id)); - - connection_number = ConnectionNumber (gdk_display); - GDK_NOTE (MISC, - g_message ("connection number: %d", connection_number)); - if (synchronize) XSynchronize (gdk_display, True); @@ -504,24 +402,15 @@ gdk_init (int *argc, timer.tv_usec = 0; timerp = NULL; - button_click_time[0] = 0; - button_click_time[1] = 0; - button_window[0] = NULL; - button_window[1] = NULL; - button_number[0] = -1; - button_number[1] = -1; - g_atexit (gdk_exit_func); + gdk_events_init (); gdk_visual_init (); gdk_window_init (); gdk_image_init (); gdk_input_init (); gdk_dnd_init (); - gdk_add_client_message_filter (gdk_wm_protocols, - gdk_wm_protocols_filter, NULL); - #ifdef USE_XIM gdk_im_open (); #endif @@ -589,630 +478,6 @@ gdk_set_locale (void) return setlocale (LC_ALL,NULL); } -/* - *-------------------------------------------------------------- - * gdk_events_pending - * - * Returns the number of events pending on the queue. - * These events have already been read from the server - * connection. - * - * Arguments: - * - * Results: - * Returns the number of events on XLib's event queue. - * - * Side effects: - * - *-------------------------------------------------------------- - */ - -gint -gdk_events_pending (void) -{ - gint result; - GList *tmp_list; - - result = XPending (gdk_display); - - tmp_list = putback_events; - while (tmp_list) - { - result++; - tmp_list = tmp_list->next; - } - - return result; -} - -/* - *-------------------------------------------------------------- - * gdk_event_get_graphics_expose - * - * Waits for a GraphicsExpose or NoExpose event - * - * Arguments: - * - * Results: - * For GraphicsExpose events, returns a pointer to the event - * converted into a GdkEvent Otherwise, returns NULL. - * - * Side effects: - * - *-------------------------------------------------------------- */ - -static Bool -graphics_expose_predicate (Display *display, - XEvent *xevent, - XPointer arg) -{ - GdkWindowPrivate *private = (GdkWindowPrivate *)arg; - - g_return_val_if_fail (private != NULL, False); - - if ((xevent->xany.window == private->xwindow) && - ((xevent->xany.type == GraphicsExpose) || - (xevent->xany.type == NoExpose))) - return True; - else - return False; -} - -GdkEvent * -gdk_event_get_graphics_expose (GdkWindow *window) -{ - XEvent xevent; - GdkEvent *event; - - g_return_val_if_fail (window != NULL, NULL); - - XIfEvent (gdk_display, &xevent, graphics_expose_predicate, (XPointer)window); - - if (xevent.xany.type == GraphicsExpose) - { - event = gdk_event_new (); - - if (gdk_event_translate (event, &xevent)) - return event; - else - gdk_event_free (event); - } - - return NULL; -} - -/************************ - * Exposure compression * - ************************/ - -/* - * The following implements simple exposure compression. It is - * modelled after the way Xt does exposure compression - in - * particular compress_expose = XtExposeCompressMultiple. - * It compress consecutive sequences of exposure events, - * but not sequences that cross other events. (This is because - * if it crosses a ConfigureNotify, we could screw up and - * mistakenly compress the exposures generated for the new - * size - could we just check for ConfigureNotify?) - * - * Xt compresses to a region / bounding rectangle, we compress - * to two rectangles, and try find the two rectangles of minimal - * area for this - this is supposed to handle the typical - * L-shaped regions generated by OpaqueMove. - */ - -/* Given three rectangles, find the two rectangles that cover - * them with the smallest area. - */ -static void -gdk_add_rect_to_rects (GdkRectangle *rect1, - GdkRectangle *rect2, - GdkRectangle *new_rect) -{ - GdkRectangle t1, t2, t3; - gint size1, size2, size3; - - gdk_rectangle_union (rect1, rect2, &t1); - gdk_rectangle_union (rect1, new_rect, &t2); - gdk_rectangle_union (rect2, new_rect, &t3); - - size1 = t1.width * t1.height + new_rect->width * new_rect->height; - size2 = t2.width * t2.height + rect2->width * rect2->height; - size3 = t1.width * t1.height + rect1->width * rect1->height; - - if (size1 < size2) - { - if (size1 < size3) - { - *rect1 = t1; - *rect2 = *new_rect; - } - else - *rect2 = t3; - } - else - { - if (size2 < size3) - *rect1 = t2; - else - *rect2 = t3; - } -} - -typedef struct _GdkExposeInfo GdkExposeInfo; - -struct _GdkExposeInfo { - Window window; - gboolean seen_nonmatching; -}; - -Bool -expose_predicate (Display *display, XEvent *xevent, XPointer arg) -{ - GdkExposeInfo *info = (GdkExposeInfo *)arg; - - if (xevent->xany.type != Expose) - { - info->seen_nonmatching = TRUE; - } - - if (info->seen_nonmatching || (xevent->xany.window != info->window)) - return FALSE; - else - return TRUE; -} - -void -gdk_compress_exposures (XEvent *xevent, GdkWindow *window) -{ - gint nrects = 1; - gint count = 0; - GdkRectangle rect1; - GdkRectangle rect2; - GdkRectangle tmp_rect; - XEvent tmp_event; - GdkFilterReturn result; - GdkExposeInfo info; - GdkEvent event; - - info.window = xevent->xany.window; - info.seen_nonmatching = FALSE; - - rect1.x = xevent->xexpose.x; - rect1.y = xevent->xexpose.y; - rect1.width = xevent->xexpose.width; - rect1.height = xevent->xexpose.height; - - while (1) - { - if (count == 0) - { - if (!XCheckIfEvent (gdk_display, - &tmp_event, - expose_predicate, - (XPointer)&info)) - break; - } - else - XIfEvent (gdk_display, - &tmp_event, - expose_predicate, - (XPointer)&info); - - /* We apply filters here, and if it was filtered, completely - * ignore the return - */ - result = gdk_event_apply_filters (xevent, &event, - window ? - ((GdkWindowPrivate *)window)->filters - : gdk_default_filters); - - if (result != GDK_FILTER_CONTINUE) - { - if (result == GDK_FILTER_TRANSLATE) - gdk_event_put (&event); - continue; - } - - if (nrects == 1) - { - rect2.x = tmp_event.xexpose.x; - rect2.y = tmp_event.xexpose.y; - rect2.width = tmp_event.xexpose.width; - rect2.height = tmp_event.xexpose.height; - - nrects++; - } - else - { - tmp_rect.x = tmp_event.xexpose.x; - tmp_rect.y = tmp_event.xexpose.y; - tmp_rect.width = tmp_event.xexpose.width; - tmp_rect.height = tmp_event.xexpose.height; - - gdk_add_rect_to_rects (&rect1, &rect2, &tmp_rect); - } - - count = tmp_event.xexpose.count; - } - - if (nrects == 2) - { - gdk_rectangle_union (&rect1, &rect2, &tmp_rect); - - if ((tmp_rect.width * tmp_rect.height) < - 2 * (rect1.height * rect1.width + - rect2.height * rect2.width)) - { - rect1 = tmp_rect; - nrects = 1; - } - } - - if (nrects == 2) - { - event.expose.type = GDK_EXPOSE; - event.expose.window = window; - event.expose.area.x = rect2.x; - event.expose.area.y = rect2.y; - event.expose.area.width = rect2.width; - event.expose.area.height = rect2.height; - event.expose.count = 0; - - gdk_event_put (&event); - } - - xevent->xexpose.count = nrects - 1; - xevent->xexpose.x = rect1.x; - xevent->xexpose.y = rect1.y; - xevent->xexpose.width = rect1.width; - xevent->xexpose.height = rect1.height; -} - -/* - *-------------------------------------------------------------- - * gdk_event_get - * - * Gets the next event. - * - * Arguments: - * - * Results: - * If an event was received that we care about, returns - * a pointer to that event, to be freed with gdk_event_free. - * Otherwise, returns NULL. This function will also return - * before an event is received if the timeout interval - * runs out. - * - * Side effects: - * - *-------------------------------------------------------------- - */ - -GdkEvent * -gdk_event_get (void) -{ - GdkEvent *event; - GList *temp_list; - XEvent xevent; - -#if 0 - if (pred) - { - temp_list = putback_events; - while (temp_list) - { - temp_event = temp_list->data; - - if ((* pred) (temp_event, data)) - { - if (event) - *event = *temp_event; - putback_events = g_list_remove_link (putback_events, temp_list); - g_list_free (temp_list); - return TRUE; - } - - temp_list = temp_list->next; - } - - event_pred.func = pred; - event_pred.data = data; - - if (XCheckIfEvent (gdk_display, &xevent, gdk_event_get_type, (XPointer) & event_pred)) - if (event) - return gdk_event_translate (event, &xevent); - } - else -#endif - if (putback_events) - { - event = putback_events->data; - - temp_list = putback_events; - putback_events = g_list_remove_link (putback_events, temp_list); - g_list_free_1 (temp_list); - - return event; - } - - /* Wait for an event to occur or the timeout to elapse. - * If an event occurs "gdk_event_wait" will return TRUE. - * If the timeout elapses "gdk_event_wait" will return - * FALSE. - */ - if (gdk_event_wait ()) - { - /* If we get here we can rest assurred that an event - * has occurred. Read it. - */ -#ifdef USE_XIM - Window w = None; - - XNextEvent (gdk_display, &xevent); - if (gdk_xim_window) - switch (xevent.type) - { - case KeyPress: - case KeyRelease: - case ButtonPress: - case ButtonRelease: - w = GDK_WINDOW_XWINDOW (gdk_xim_window); - break; - } - - if (XFilterEvent (&xevent, w)) - return NULL; -#else - XNextEvent (gdk_display, &xevent); -#endif - - event = gdk_event_new (); - - event->any.type = GDK_NOTHING; - event->any.window = NULL; - event->any.send_event = FALSE; - event->any.send_event = xevent.xany.send_event; - - if (gdk_event_translate (event, &xevent)) - return event; - else - gdk_event_free (event); - } - - return NULL; -} - -void -gdk_event_put (GdkEvent *event) -{ - GdkEvent *new_event; - - g_return_if_fail (event != NULL); - - new_event = gdk_event_copy (event); - - putback_events = g_list_prepend (putback_events, new_event); -} - -/* - *-------------------------------------------------------------- - * gdk_event_copy - * - * Copy a event structure into new storage. - * - * Arguments: - * "event" is the event struct to copy. - * - * Results: - * A new event structure. Free it with gdk_event_free. - * - * Side effects: - * The reference count of the window in the event is increased. - * - *-------------------------------------------------------------- - */ - -static GMemChunk *event_chunk; - -static GdkEvent* -gdk_event_new (void) -{ - GdkEvent *new_event; - - if (event_chunk == NULL) - event_chunk = g_mem_chunk_new ("events", - sizeof (GdkEvent), - 4096, - G_ALLOC_AND_FREE); - - new_event = g_chunk_new (GdkEvent, event_chunk); - - return new_event; -} - -GdkEvent* -gdk_event_copy (GdkEvent *event) -{ - GdkEvent *new_event; - - g_return_val_if_fail (event != NULL, NULL); - - new_event = gdk_event_new (); - - *new_event = *event; - gdk_window_ref (new_event->any.window); - - switch (event->any.type) - { - case GDK_KEY_PRESS: - case GDK_KEY_RELEASE: - new_event->key.string = g_strdup (event->key.string); - break; - - case GDK_ENTER_NOTIFY: - case GDK_LEAVE_NOTIFY: - if (event->crossing.subwindow != NULL) - gdk_window_ref (event->crossing.subwindow); - break; - - case GDK_DRAG_ENTER: - case GDK_DRAG_LEAVE: - case GDK_DRAG_MOTION: - case GDK_DRAG_STATUS: - case GDK_DROP_START: - case GDK_DROP_FINISHED: - gdk_drag_context_ref (event->dnd.context); - break; - - - default: - break; - } - - return new_event; -} - -/* - *-------------------------------------------------------------- - * gdk_event_free - * - * Free a event structure obtained from gdk_event_copy. Do not use - * with other event structures. - * - * Arguments: - * "event" is the event struct to free. - * - * Results: - * - * Side effects: - * The reference count of the window in the event is decreased and - * might be freed, too. - * - *-------------------------------------------------------------- */ - -void -gdk_event_free (GdkEvent *event) -{ - g_assert (event_chunk != NULL); - g_return_if_fail (event != NULL); - - if (event->any.window) - gdk_window_unref (event->any.window); - - switch (event->any.type) - { - case GDK_KEY_PRESS: - case GDK_KEY_RELEASE: - g_free (event->key.string); - break; - - case GDK_ENTER_NOTIFY: - case GDK_LEAVE_NOTIFY: - if (event->crossing.subwindow != NULL) - gdk_window_unref (event->crossing.subwindow); - break; - - case GDK_DRAG_ENTER: - case GDK_DRAG_LEAVE: - case GDK_DRAG_MOTION: - case GDK_DRAG_STATUS: - case GDK_DROP_START: - case GDK_DROP_FINISHED: - gdk_drag_context_unref (event->dnd.context); - break; - - - default: - break; - } - - g_mem_chunk_free (event_chunk, event); -} - -/* - *-------------------------------------------------------------- - * gdk_set_show_events - * - * Turns on/off the showing of events. - * - * Arguments: - * "show_events" is a boolean describing whether or - * not to show the events gdk receives. - * - * Results: - * - * Side effects: - * When "show_events" is TRUE, calls to "gdk_event_get" - * will output debugging informatin regarding the event - * received to stdout. - * - *-------------------------------------------------------------- - */ - -/* - *-------------------------------------------------------------- - * gdk_event_get_time: - * Get the timestamp from an event. - * arguments: - * event: - * results: - * The event's time stamp, if it has one, otherwise - * GDK_CURRENT_TIME. - *-------------------------------------------------------------- - */ - -guint32 -gdk_event_get_time (GdkEvent *event) -{ - if (event) - switch (event->type) - { - case GDK_MOTION_NOTIFY: - return event->motion.time; - case GDK_BUTTON_PRESS: - case GDK_2BUTTON_PRESS: - case GDK_3BUTTON_PRESS: - case GDK_BUTTON_RELEASE: - return event->button.time; - case GDK_KEY_PRESS: - case GDK_KEY_RELEASE: - return event->key.time; - case GDK_ENTER_NOTIFY: - case GDK_LEAVE_NOTIFY: - return event->crossing.time; - case GDK_PROPERTY_NOTIFY: - return event->property.time; - case GDK_SELECTION_CLEAR: - case GDK_SELECTION_REQUEST: - case GDK_SELECTION_NOTIFY: - return event->selection.time; - case GDK_PROXIMITY_IN: - case GDK_PROXIMITY_OUT: - return event->proximity.time; - case GDK_DRAG_ENTER: - case GDK_DRAG_LEAVE: - case GDK_DRAG_MOTION: - case GDK_DRAG_STATUS: - case GDK_DROP_START: - case GDK_DROP_FINISHED: - return event->dnd.time; - default: /* use current time */ - break; - } - - return GDK_CURRENT_TIME; -} - -void -gdk_set_show_events (int show_events) -{ - if (show_events) - gdk_debug_flags |= GDK_DEBUG_EVENTS; - else - gdk_debug_flags &= ~GDK_DEBUG_EVENTS; -} - void gdk_set_use_xshm (gint use_xshm) { @@ -1220,12 +485,6 @@ gdk_set_use_xshm (gint use_xshm) } gint -gdk_get_show_events (void) -{ - return gdk_debug_flags & GDK_DEBUG_EVENTS; -} - -gint gdk_get_use_xshm (void) { return gdk_use_xshm; @@ -1337,89 +596,6 @@ gdk_timer_disable (void) timerp = NULL; } -gint -gdk_input_add_full (gint source, - GdkInputCondition condition, - GdkInputFunction function, - gpointer data, - GdkDestroyNotify destroy) -{ - static gint next_tag = 1; - GList *list; - GdkInput *input; - gint tag; - - tag = 0; - list = inputs; - - while (list) - { - input = list->data; - list = list->next; - - if ((input->source == source) && (input->condition == condition)) - { - if (input->destroy) - (input->destroy) (input->data); - input->function = function; - input->data = data; - input->destroy = destroy; - tag = input->tag; - } - } - - if (!tag) - { - input = g_new (GdkInput, 1); - input->tag = next_tag++; - input->source = source; - input->condition = condition; - input->function = function; - input->data = data; - input->destroy = destroy; - tag = input->tag; - - inputs = g_list_prepend (inputs, input); - } - - return tag; -} - -gint -gdk_input_add (gint source, - GdkInputCondition condition, - GdkInputFunction function, - gpointer data) -{ - return gdk_input_add_interp (source, condition, function, data, NULL); -} - -void -gdk_input_remove (gint tag) -{ - GList *list; - GdkInput *input; - - list = inputs; - while (list) - { - input = list->data; - - if (input->tag == tag) - { - if (input->destroy) - (input->destroy) (input->data); - - input->tag = 0; /* do not free it here */ - input->condition = 0; /* it's done in gdk_event_wait */ - - break; - } - - list = list->next; - } -} - /* *-------------------------------------------------------------- * gdk_pointer_grab @@ -1452,9 +628,6 @@ gdk_pointer_grab (GdkWindow * window, guint32 time) { /* From gdkwindow.c */ - extern const int nevent_masks; - extern const int event_mask_table[]; - gint return_val; GdkWindowPrivate *window_private; GdkWindowPrivate *confine_to_private; @@ -1485,10 +658,10 @@ gdk_pointer_grab (GdkWindow * window, xevent_mask = 0; - for (i = 0; i < nevent_masks; i++) + for (i = 0; i < gdk_nevent_masks; i++) { if (event_mask & (1 << (i + 1))) - xevent_mask |= event_mask_table[i]; + xevent_mask |= gdk_event_mask_table[i]; } if (gdk_input_vtable.grab_pointer) @@ -1516,7 +689,7 @@ gdk_pointer_grab (GdkWindow * window, } if (return_val == GrabSuccess) - xgrab_window = window_private; + gdk_xgrab_window = window_private; return return_val; } @@ -1543,7 +716,7 @@ gdk_pointer_ungrab (guint32 time) gdk_input_vtable.ungrab_pointer (time); XUngrabPointer (gdk_display, time); - xgrab_window = NULL; + gdk_xgrab_window = NULL; } /* @@ -1564,7 +737,7 @@ gdk_pointer_ungrab (guint32 time) gint gdk_pointer_is_grabbed (void) { - return xgrab_window != NULL; + return gdk_xgrab_window != NULL; } /* @@ -1747,1240 +920,12 @@ gdk_key_repeat_restore (void) } -/* - *-------------------------------------------------------------- - * gdk_flush - * - * Flushes the Xlib output buffer and then waits - * until all requests have been received and processed - * by the X server. The only real use for this function - * is in dealing with XShm. - * - * Arguments: - * - * Results: - * - * Side effects: - * - *-------------------------------------------------------------- - */ - -void gdk_flush (void) -{ - XSync (gdk_display, False); -} - - void gdk_beep (void) { XBell(gdk_display, 100); } - -/* - *-------------------------------------------------------------- - * gdk_event_wait - * - * Waits until an event occurs or the timer runs out. - * - * Arguments: - * - * Results: - * Returns TRUE if an event is ready to be read and FALSE - * if the timer ran out. - * - * Side effects: - * - *-------------------------------------------------------------- - */ - -static gint -gdk_event_wait (void) -{ - GList *list; - GList *temp_list; - GdkInput *input; - GdkInputCondition condition; - SELECT_MASK readfds; - SELECT_MASK writefds; - SELECT_MASK exceptfds; - int max_input; - int nfd; - - /* If there are no events pending we will wait for an event. - * The time we wait is dependant on the "timer". If no timer - * has been specified then we'll block until an event arrives. - * If a timer has been specified we'll block until an event - * arrives or the timer expires. (This is all done using the - * "select" system call). - */ - - if (XPending (gdk_display) == 0) - { - FD_ZERO (&readfds); - FD_ZERO (&writefds); - FD_ZERO (&exceptfds); - - FD_SET (connection_number, &readfds); - max_input = connection_number; - - list = inputs; - while (list) - { - input = list->data; - - if (input->tag) - { - if (input->condition & GDK_INPUT_READ) - FD_SET (input->source, &readfds); - if (input->condition & GDK_INPUT_WRITE) - FD_SET (input->source, &writefds); - if (input->condition & GDK_INPUT_EXCEPTION) - FD_SET (input->source, &exceptfds); - - max_input = MAX (max_input, input->source); - list = list->next; - } - else /* free removed inputs */ - { - temp_list = list; - - if (list->next) - list->next->prev = list->prev; - if (list->prev) - list->prev->next = list->next; - if (inputs == list) - inputs = list->next; - - list = list->next; - - temp_list->next = NULL; - temp_list->prev = NULL; - - g_free (temp_list->data); - g_list_free (temp_list); - } - } - -#ifdef USE_PTHREADS - if (gdk_using_threads) - { - gdk_select_waiting = TRUE; - - FD_SET (gdk_threads_pipe[0], &readfds); - max_input = MAX (max_input, gdk_threads_pipe[0]); - gdk_threads_leave (); - } -#endif - - nfd = select (max_input+1, &readfds, &writefds, &exceptfds, timerp); - -#ifdef USE_PTHREADS - if (gdk_using_threads) - { - gchar c; - gdk_threads_enter (); - gdk_select_waiting = FALSE; - - if (FD_ISSET (gdk_threads_pipe[0], &readfds)) - read (gdk_threads_pipe[0], &c, 1); - } -#endif - - timerp = NULL; - timer_val = 0; - - if (nfd > 0) - { - if (FD_ISSET (connection_number, &readfds)) - { - if (XPending (gdk_display) == 0) - { - if (nfd == 1) - { - XNoOp (gdk_display); - XFlush (gdk_display); - } - return FALSE; - } - else - return TRUE; - } - - list = inputs; - while (list) - { - input = list->data; - list = list->next; - - condition = 0; - if (FD_ISSET (input->source, &readfds)) - condition |= GDK_INPUT_READ; - if (FD_ISSET (input->source, &writefds)) - condition |= GDK_INPUT_WRITE; - if (FD_ISSET (input->source, &exceptfds)) - condition |= GDK_INPUT_EXCEPTION; - - if (condition && input->function) - (* input->function) (input->data, input->source, condition); - } - } - } - else - return TRUE; - - return FALSE; -} - -static gint -gdk_event_apply_filters (XEvent *xevent, - GdkEvent *event, - GList *filters) -{ - GdkEventFilter *filter; - GList *tmp_list; - GdkFilterReturn result; - - tmp_list = filters; - - while (tmp_list) - { - filter = (GdkEventFilter *)tmp_list->data; - - result = (*filter->function)(xevent, event, filter->data); - if (result != GDK_FILTER_CONTINUE) - return result; - - tmp_list = tmp_list->next; - } - - return GDK_FILTER_CONTINUE; -} - -void -gdk_add_client_message_filter (GdkAtom message_type, - GdkFilterFunc func, - gpointer data) -{ - GdkClientFilter *filter = g_new (GdkClientFilter, 1); - - filter->type = message_type; - filter->function = func; - filter->data = data; - - client_filters = g_list_prepend (client_filters, filter); -} - -static gint -gdk_event_translate (GdkEvent *event, - XEvent *xevent) -{ - - GdkWindow *window; - GdkWindowPrivate *window_private; - static XComposeStatus compose; - KeySym keysym; - int charcount; -#ifdef USE_XIM - static gchar* buf = NULL; - static gint buf_len= 0; -#else - char buf[16]; -#endif - gint return_val; - - return_val = FALSE; - - /* Find the GdkWindow that this event occurred in. - * - * We handle events with window=None - * specially - they are generated by XFree86's XInput under - * some circumstances. - */ - - if ((xevent->xany.window == None) && - gdk_input_vtable.window_none_event) - { - return_val = gdk_input_vtable.window_none_event (event,xevent); - - if (return_val >= 0) /* was handled */ - return return_val; - else - return_val = FALSE; - } - - window = gdk_window_lookup (xevent->xany.window); - window_private = (GdkWindowPrivate *) window; - - if (window != NULL) - gdk_window_ref (window); - - event->any.window = window; - event->any.send_event = xevent->xany.send_event; - - if (window_private && window_private->destroyed) - { - if (xevent->type != DestroyNotify) - return FALSE; - } - else - { - /* Check for filters for this window */ - - GdkFilterReturn result; - -#ifdef USE_XIM - if (window == NULL && - xevent->type == KeyPress && - gdk_xim_window && - !((GdkWindowPrivate *) gdk_xim_window)->destroyed) - { - /* - * If user presses a key in Preedit or Status window, keypress event - * is sometimes sent to these windows. These windows are not managed - * by GDK, so we redirect KeyPress event to gdk_xim_window. - * - * If someone want to use the window whitch is not managed by GDK - * and want to get KeyPress event, he/she must register the filter - * function to gdk_default_filters to intercept the event. - */ - - window = gdk_xim_window; - window_private = (GdkWindowPrivate *) window; - gdk_window_ref (window); - event->any.window = window; - - GDK_NOTE (XIM, - g_message ("KeyPress event is redirected to gdk_xim_window: %#lx", - xevent->xany.window)); - } -#endif /* USE_XIM */ - - result = gdk_event_apply_filters (xevent, event, - window_private - ?window_private->filters - :gdk_default_filters); - - if (result != GDK_FILTER_CONTINUE) - return (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE; - } - - if (window == NULL) - g_message ("Got event for unknown window: %#lx\n", xevent->xany.window); - - /* We do a "manual" conversion of the XEvent to a - * GdkEvent. The structures are mostly the same so - * the conversion is fairly straightforward. We also - * optionally print debugging info regarding events - * received. - */ - - return_val = TRUE; - - switch (xevent->type) - { - case KeyPress: - /* Lookup the string corresponding to the given keysym. - */ -#ifdef USE_XIM - if (buf_len == 0) - { - buf_len = 128; - buf = g_new (gchar, buf_len); - } - keysym = GDK_VoidSymbol; - - if (gdk_xim_ic && gdk_xim_ic->xic) - { - Status status; - - /* Clear keyval. Depending on status, may not be set */ - charcount = XmbLookupString(gdk_xim_ic->xic, - &xevent->xkey, buf, buf_len-1, - &keysym, &status); - if (status == XBufferOverflow) - { /* retry */ - /* alloc adequate size of buffer */ - GDK_NOTE (XIM, - g_message("XIM: overflow (required %i)", charcount)); - - while (buf_len <= charcount) - buf_len *= 2; - buf = (gchar *) g_realloc (buf, buf_len); - - charcount = XmbLookupString (gdk_xim_ic->xic, - &xevent->xkey, buf, buf_len-1, - &keysym, &status); - } - if (status == XLookupNone) - { - return_val = FALSE; - break; - } - } - else - charcount = XLookupString (&xevent->xkey, buf, buf_len, - &keysym, &compose); -#else - charcount = XLookupString (&xevent->xkey, buf, 16, - &keysym, &compose); -#endif - event->key.keyval = keysym; - - if (charcount > 0 && buf[charcount-1] == '\0') - charcount --; - else - buf[charcount] = '\0'; - - /* Print debugging info. - */ -#ifdef G_ENABLE_DEBUG - if (gdk_debug_flags & GDK_DEBUG_EVENTS) - { - g_message ("key press:\twindow: %ld key: %12s %d", - xevent->xkey.window - base_id, - event->key.keyval ? XKeysymToString (event->key.keyval) : "(none)", - event->key.keyval); - if (charcount > 0) - g_message ("\t\tlength: %4d string: \"%s\"", - charcount, buf); - } -#endif /* G_ENABLE_DEBUG */ - - event->key.type = GDK_KEY_PRESS; - event->key.window = window; - event->key.time = xevent->xkey.time; - event->key.state = (GdkModifierType) xevent->xkey.state; - event->key.string = g_strdup (buf); - event->key.length = charcount; - - break; - - case KeyRelease: - /* Lookup the string corresponding to the given keysym. - */ -#ifdef USE_XIM - if (buf_len == 0) - { - buf_len = 128; - buf = g_new (gchar, buf_len); - } -#endif - keysym = GDK_VoidSymbol; - charcount = XLookupString (&xevent->xkey, buf, 16, - &keysym, &compose); - event->key.keyval = keysym; - - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_message ("key release:\t\twindow: %ld key: %12s %d", - xevent->xkey.window - base_id, - XKeysymToString (event->key.keyval), - event->key.keyval)); - - event->key.type = GDK_KEY_RELEASE; - event->key.window = window; - event->key.time = xevent->xkey.time; - event->key.state = (GdkModifierType) xevent->xkey.state; - event->key.length = 0; - event->key.string = NULL; - - break; - - case ButtonPress: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_message ("button press:\t\twindow: %ld x,y: %d %d button: %d", - xevent->xbutton.window - base_id, - xevent->xbutton.x, xevent->xbutton.y, - xevent->xbutton.button)); - - if (window_private && - (window_private->extension_events != 0) && - gdk_input_ignore_core) - { - return_val = FALSE; - break; - } - - event->button.type = GDK_BUTTON_PRESS; - event->button.window = window; - event->button.time = xevent->xbutton.time; - event->button.x = xevent->xbutton.x; - event->button.y = xevent->xbutton.y; - event->button.x_root = (gfloat)xevent->xbutton.x_root; - event->button.y_root = (gfloat)xevent->xbutton.y_root; - event->button.pressure = 0.5; - event->button.xtilt = 0; - event->button.ytilt = 0; - event->button.state = (GdkModifierType) xevent->xbutton.state; - event->button.button = xevent->xbutton.button; - event->button.source = GDK_SOURCE_MOUSE; - event->button.deviceid = GDK_CORE_POINTER; - - if ((event->button.time < (button_click_time[1] + TRIPLE_CLICK_TIME)) && - (event->button.window == button_window[1]) && - (event->button.button == button_number[1])) - { - gdk_synthesize_click (event, 3); - - button_click_time[1] = 0; - button_click_time[0] = 0; - button_window[1] = NULL; - button_window[0] = 0; - button_number[1] = -1; - button_number[0] = -1; - } - else if ((event->button.time < (button_click_time[0] + DOUBLE_CLICK_TIME)) && - (event->button.window == button_window[0]) && - (event->button.button == button_number[0])) - { - gdk_synthesize_click (event, 2); - - button_click_time[1] = button_click_time[0]; - button_click_time[0] = event->button.time; - button_window[1] = button_window[0]; - button_window[0] = event->button.window; - button_number[1] = button_number[0]; - button_number[0] = event->button.button; - } - else - { - button_click_time[1] = 0; - button_click_time[0] = event->button.time; - button_window[1] = NULL; - button_window[0] = event->button.window; - button_number[1] = -1; - button_number[0] = event->button.button; - } - - break; - - case ButtonRelease: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_message ("button release:\twindow: %ld x,y: %d %d button: %d", - xevent->xbutton.window - base_id, - xevent->xbutton.x, xevent->xbutton.y, - xevent->xbutton.button)); - - if (window_private && - (window_private->extension_events != 0) && - gdk_input_ignore_core) - { - return_val = FALSE; - break; - } - - event->button.type = GDK_BUTTON_RELEASE; - event->button.window = window; - event->button.time = xevent->xbutton.time; - event->button.x = xevent->xbutton.x; - event->button.y = xevent->xbutton.y; - event->button.x_root = (gfloat)xevent->xbutton.x_root; - event->button.y_root = (gfloat)xevent->xbutton.y_root; - event->button.pressure = 0.5; - event->button.xtilt = 0; - event->button.ytilt = 0; - event->button.state = (GdkModifierType) xevent->xbutton.state; - event->button.button = xevent->xbutton.button; - event->button.source = GDK_SOURCE_MOUSE; - event->button.deviceid = GDK_CORE_POINTER; - - break; - - case MotionNotify: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_message ("motion notify:\t\twindow: %ld x,y: %d %d hint: %s", - xevent->xmotion.window - base_id, - xevent->xmotion.x, xevent->xmotion.y, - (xevent->xmotion.is_hint) ? "true" : "false")); - - if (window_private && - (window_private->extension_events != 0) && - gdk_input_ignore_core) - { - return_val = FALSE; - break; - } - - event->motion.type = GDK_MOTION_NOTIFY; - event->motion.window = window; - event->motion.time = xevent->xmotion.time; - event->motion.x = xevent->xmotion.x; - event->motion.y = xevent->xmotion.y; - event->motion.x_root = (gfloat)xevent->xmotion.x_root; - event->motion.y_root = (gfloat)xevent->xmotion.y_root; - event->motion.pressure = 0.5; - event->motion.xtilt = 0; - event->motion.ytilt = 0; - event->motion.state = (GdkModifierType) xevent->xmotion.state; - event->motion.is_hint = xevent->xmotion.is_hint; - event->motion.source = GDK_SOURCE_MOUSE; - event->motion.deviceid = GDK_CORE_POINTER; - - break; - - case EnterNotify: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_message ("enter notify:\t\twindow: %ld detail: %d subwin: %ld", - xevent->xcrossing.window - base_id, - xevent->xcrossing.detail, - xevent->xcrossing.subwindow - base_id)); - - /* Tell XInput stuff about it if appropriate */ - if (window_private && - !window_private->destroyed && - (window_private->extension_events != 0) && - gdk_input_vtable.enter_event) - gdk_input_vtable.enter_event (&xevent->xcrossing, window); - - event->crossing.type = GDK_ENTER_NOTIFY; - event->crossing.window = window; - - /* If the subwindow field of the XEvent is non-NULL, then - * lookup the corresponding GdkWindow. - */ - if (xevent->xcrossing.subwindow != None) - event->crossing.subwindow = gdk_window_lookup (xevent->xcrossing.subwindow); - else - event->crossing.subwindow = NULL; - - event->crossing.time = xevent->xcrossing.time; - event->crossing.x = xevent->xcrossing.x; - event->crossing.y = xevent->xcrossing.y; - event->crossing.x_root = xevent->xcrossing.x_root; - event->crossing.y_root = xevent->xcrossing.y_root; - - /* Translate the crossing mode into Gdk terms. - */ - switch (xevent->xcrossing.mode) - { - case NotifyNormal: - event->crossing.mode = GDK_CROSSING_NORMAL; - break; - case NotifyGrab: - event->crossing.mode = GDK_CROSSING_GRAB; - break; - case NotifyUngrab: - event->crossing.mode = GDK_CROSSING_UNGRAB; - break; - }; - - /* Translate the crossing detail into Gdk terms. - */ - switch (xevent->xcrossing.detail) - { - case NotifyInferior: - event->crossing.detail = GDK_NOTIFY_INFERIOR; - break; - case NotifyAncestor: - event->crossing.detail = GDK_NOTIFY_ANCESTOR; - break; - case NotifyVirtual: - event->crossing.detail = GDK_NOTIFY_VIRTUAL; - break; - case NotifyNonlinear: - event->crossing.detail = GDK_NOTIFY_NONLINEAR; - break; - case NotifyNonlinearVirtual: - event->crossing.detail = GDK_NOTIFY_NONLINEAR_VIRTUAL; - break; - default: - event->crossing.detail = GDK_NOTIFY_UNKNOWN; - break; - } - - event->crossing.focus = xevent->xcrossing.focus; - event->crossing.state = xevent->xcrossing.state; - - break; - - case LeaveNotify: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_message ("leave notify:\t\twindow: %ld detail: %d subwin: %ld", - xevent->xcrossing.window - base_id, - xevent->xcrossing.detail, xevent->xcrossing.subwindow - base_id)); - - event->crossing.type = GDK_LEAVE_NOTIFY; - event->crossing.window = window; - - /* If the subwindow field of the XEvent is non-NULL, then - * lookup the corresponding GdkWindow. - */ - if (xevent->xcrossing.subwindow != None) - event->crossing.subwindow = gdk_window_lookup (xevent->xcrossing.subwindow); - else - event->crossing.subwindow = NULL; - - event->crossing.time = xevent->xcrossing.time; - event->crossing.x = xevent->xcrossing.x; - event->crossing.y = xevent->xcrossing.y; - event->crossing.x_root = xevent->xcrossing.x_root; - event->crossing.y_root = xevent->xcrossing.y_root; - - /* Translate the crossing mode into Gdk terms. - */ - switch (xevent->xcrossing.mode) - { - case NotifyNormal: - event->crossing.mode = GDK_CROSSING_NORMAL; - break; - case NotifyGrab: - event->crossing.mode = GDK_CROSSING_GRAB; - break; - case NotifyUngrab: - event->crossing.mode = GDK_CROSSING_UNGRAB; - break; - }; - - /* Translate the crossing detail into Gdk terms. - */ - switch (xevent->xcrossing.detail) - { - case NotifyInferior: - event->crossing.detail = GDK_NOTIFY_INFERIOR; - break; - case NotifyAncestor: - event->crossing.detail = GDK_NOTIFY_ANCESTOR; - break; - case NotifyVirtual: - event->crossing.detail = GDK_NOTIFY_VIRTUAL; - break; - case NotifyNonlinear: - event->crossing.detail = GDK_NOTIFY_NONLINEAR; - break; - case NotifyNonlinearVirtual: - event->crossing.detail = GDK_NOTIFY_NONLINEAR_VIRTUAL; - break; - default: - event->crossing.detail = GDK_NOTIFY_UNKNOWN; - break; - } - - event->crossing.focus = xevent->xcrossing.focus; - event->crossing.state = xevent->xcrossing.state; - - break; - - case FocusIn: - case FocusOut: - /* We only care about focus events that indicate that _this_ - * window (not a ancestor or child) got or lost the focus - */ - switch (xevent->xfocus.detail) - { - case NotifyAncestor: - case NotifyInferior: - case NotifyNonlinear: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_message ("focus %s:\t\twindow: %ld", - (xevent->xany.type == FocusIn) ? "in" : "out", - xevent->xfocus.window - base_id)); - - /* gdk_keyboard_grab() causes following events. These events confuse - * the XIM focus, so ignore them. - */ - if (xevent->xfocus.mode == NotifyGrab || - xevent->xfocus.mode == NotifyUngrab) - break; - - event->focus_change.type = GDK_FOCUS_CHANGE; - event->focus_change.window = window; - event->focus_change.in = (xevent->xany.type == FocusIn); - - break; - default: - return_val = FALSE; - } - break; - - case KeymapNotify: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_message ("keymap notify")); - - /* Not currently handled */ - return_val = FALSE; - break; - - case Expose: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_message ("expose:\t\twindow: %ld %d x,y: %d %d w,h: %d %d", - xevent->xexpose.window - base_id, xevent->xexpose.count, - xevent->xexpose.x, xevent->xexpose.y, - xevent->xexpose.width, xevent->xexpose.height)); - gdk_compress_exposures (xevent, window); - - event->expose.type = GDK_EXPOSE; - event->expose.window = window; - event->expose.area.x = xevent->xexpose.x; - event->expose.area.y = xevent->xexpose.y; - event->expose.area.width = xevent->xexpose.width; - event->expose.area.height = xevent->xexpose.height; - event->expose.count = xevent->xexpose.count; - - break; - - case GraphicsExpose: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_message ("graphics expose:\tdrawable: %ld", - xevent->xgraphicsexpose.drawable - base_id)); - - event->expose.type = GDK_EXPOSE; - event->expose.window = window; - event->expose.area.x = xevent->xgraphicsexpose.x; - event->expose.area.y = xevent->xgraphicsexpose.y; - event->expose.area.width = xevent->xgraphicsexpose.width; - event->expose.area.height = xevent->xgraphicsexpose.height; - event->expose.count = xevent->xexpose.count; - - break; - - case NoExpose: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_message ("no expose:\t\tdrawable: %ld", - xevent->xnoexpose.drawable - base_id)); - - event->no_expose.type = GDK_NO_EXPOSE; - event->no_expose.window = window; - - break; - - case VisibilityNotify: - /* Print debugging info. - */ -#ifdef G_ENABLE_DEBUG - if (gdk_debug_flags & GDK_DEBUG_EVENTS) - switch (xevent->xvisibility.state) - { - case VisibilityFullyObscured: - g_message ("visibility notify:\twindow: %ld none", - xevent->xvisibility.window - base_id); - break; - case VisibilityPartiallyObscured: - g_message ("visibility notify:\twindow: %ld partial", - xevent->xvisibility.window - base_id); - break; - case VisibilityUnobscured: - g_message ("visibility notify:\twindow: %ld full", - xevent->xvisibility.window - base_id); - break; - } -#endif /* G_ENABLE_DEBUG */ - - event->visibility.type = GDK_VISIBILITY_NOTIFY; - event->visibility.window = window; - - switch (xevent->xvisibility.state) - { - case VisibilityFullyObscured: - event->visibility.state = GDK_VISIBILITY_FULLY_OBSCURED; - break; - - case VisibilityPartiallyObscured: - event->visibility.state = GDK_VISIBILITY_PARTIAL; - break; - - case VisibilityUnobscured: - event->visibility.state = GDK_VISIBILITY_UNOBSCURED; - break; - } - - break; - - case CreateNotify: - /* Not currently handled */ - break; - - case DestroyNotify: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_message ("destroy notify:\twindow: %ld", - xevent->xdestroywindow.window - base_id)); - - event->any.type = GDK_DESTROY; - event->any.window = window; - - return_val = window_private && !window_private->destroyed; - - if(window && window_private->xwindow != GDK_ROOT_WINDOW()) - gdk_window_destroy_notify (window); - break; - - case UnmapNotify: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_message ("unmap notify:\t\twindow: %ld", - xevent->xmap.window - base_id)); - - event->any.type = GDK_UNMAP; - event->any.window = window; - - if (xgrab_window == window_private) - xgrab_window = NULL; - - break; - - case MapNotify: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_message ("map notify:\t\twindow: %ld", - xevent->xmap.window - base_id)); - - event->any.type = GDK_MAP; - event->any.window = window; - - break; - - case ReparentNotify: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_message ("reparent notify:\twindow: %ld", - xevent->xreparent.window - base_id)); - - /* Not currently handled */ - return_val = FALSE; - break; - - case ConfigureNotify: - /* Print debugging info. - */ - while ((XPending (gdk_display) > 0) && - XCheckTypedWindowEvent(gdk_display, xevent->xany.window, - ConfigureNotify, xevent)) - { - GdkFilterReturn result; - - GDK_NOTE (EVENTS, - g_message ("configure notify discarded:\twindow: %ld", - xevent->xconfigure.window - base_id)); - - result = gdk_event_apply_filters (xevent, event, - window_private - ?window_private->filters - :gdk_default_filters); - - /* If the result is GDK_FILTER_REMOVE, there will be - * trouble, but anybody who filtering the Configure events - * better know what they are doing - */ - if (result != GDK_FILTER_CONTINUE) - { - return (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE; - } - - /*XSync (gdk_display, 0);*/ - } - - - GDK_NOTE (EVENTS, - g_message ("configure notify:\twindow: %ld x,y: %d %d w,h: %d %d b-w: %d above: %ld ovr: %d", - xevent->xconfigure.window - base_id, - xevent->xconfigure.x, - xevent->xconfigure.y, - xevent->xconfigure.width, - xevent->xconfigure.height, - xevent->xconfigure.border_width, - xevent->xconfigure.above - base_id, - xevent->xconfigure.override_redirect)); - - if (!window_private->destroyed && - (window_private->extension_events != 0) && - gdk_input_vtable.configure_event) - gdk_input_vtable.configure_event (&xevent->xconfigure, window); - - if (window_private->window_type == GDK_WINDOW_CHILD) - return_val = FALSE; - else - { - event->configure.type = GDK_CONFIGURE; - event->configure.window = window; - event->configure.width = xevent->xconfigure.width; - event->configure.height = xevent->xconfigure.height; - - if (!xevent->xconfigure.x && - !xevent->xconfigure.y && - !window_private->destroyed) - { - gint tx = 0; - gint ty = 0; - Window child_window = 0; - - if (!XTranslateCoordinates (window_private->xdisplay, - window_private->xwindow, - gdk_root_window, - 0, 0, - &tx, &ty, - &child_window)) - g_warning ("GdkWindow %ld doesn't share root windows display?", - window_private->xwindow - base_id); - event->configure.x = tx; - event->configure.y = ty; - } - else - { - event->configure.x = xevent->xconfigure.x; - event->configure.y = xevent->xconfigure.y; - } - window_private->x = event->configure.x; - window_private->y = event->configure.y; - window_private->width = xevent->xconfigure.width; - window_private->height = xevent->xconfigure.height; - if (window_private->resize_count > 1) - window_private->resize_count -= 1; - } - break; - - case PropertyNotify: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_message ("property notify:\twindow: %ld", - xevent->xproperty.window - base_id)); - - event->property.type = GDK_PROPERTY_NOTIFY; - event->property.window = window; - event->property.atom = xevent->xproperty.atom; - event->property.time = xevent->xproperty.time; - event->property.state = xevent->xproperty.state; - - break; - - case SelectionClear: - GDK_NOTE (EVENTS, - g_message ("selection clear:\twindow: %ld", - xevent->xproperty.window - base_id)); - - event->selection.type = GDK_SELECTION_CLEAR; - event->selection.window = window; - event->selection.selection = xevent->xselectionclear.selection; - event->selection.time = xevent->xselectionclear.time; - - break; - - case SelectionRequest: - GDK_NOTE (EVENTS, - g_message ("selection request:\twindow: %ld", - xevent->xproperty.window - base_id)); - - event->selection.type = GDK_SELECTION_REQUEST; - event->selection.window = window; - event->selection.selection = xevent->xselectionrequest.selection; - event->selection.target = xevent->xselectionrequest.target; - event->selection.property = xevent->xselectionrequest.property; - event->selection.requestor = xevent->xselectionrequest.requestor; - event->selection.time = xevent->xselectionrequest.time; - - break; - - case SelectionNotify: - GDK_NOTE (EVENTS, - g_message ("selection notify:\twindow: %ld", - xevent->xproperty.window - base_id)); - - - event->selection.type = GDK_SELECTION_NOTIFY; - event->selection.window = window; - event->selection.selection = xevent->xselection.selection; - event->selection.target = xevent->xselection.target; - event->selection.property = xevent->xselection.property; - event->selection.time = xevent->xselection.time; - - break; - - case ColormapNotify: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_message ("colormap notify:\twindow: %ld", - xevent->xcolormap.window - base_id)); - - /* Not currently handled */ - return_val = FALSE; - break; - - case ClientMessage: - { - GList *tmp_list; - GdkFilterReturn result = GDK_FILTER_CONTINUE; - - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_message ("client message:\twindow: %ld", - xevent->xclient.window - base_id)); - - tmp_list = client_filters; - while (tmp_list) - { - GdkClientFilter *filter = tmp_list->data; - if (filter->type == xevent->xclient.message_type) - { - result = (*filter->function) (xevent, event, filter->data); - break; - } - - tmp_list = tmp_list->next; - } - - switch (result) - { - case GDK_FILTER_REMOVE: - return_val = FALSE; - break; - case GDK_FILTER_TRANSLATE: - return_val = TRUE; - break; - case GDK_FILTER_CONTINUE: - /* Send unknown ClientMessage's on to Gtk for it to use */ - event->client.type = GDK_CLIENT_EVENT; - event->client.window = window; - event->client.message_type = xevent->xclient.message_type; - event->client.data_format = xevent->xclient.format; - memcpy(&event->client.data, &xevent->xclient.data, - sizeof(event->client.data)); - } - } - - break; - - case MappingNotify: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_message ("mapping notify")); - - /* Let XLib know that there is a new keyboard mapping. - */ - XRefreshKeyboardMapping (&xevent->xmapping); - return_val = FALSE; - break; - - default: - /* something else - (e.g., a Xinput event) */ - - if (window_private && - !window_private->destroyed && - (window_private->extension_events != 0) && - gdk_input_vtable.other_event) - return_val = gdk_input_vtable.other_event(event, xevent, window); - else - return_val = FALSE; - - break; - } - - if (return_val) - { - if (event->any.window) - gdk_window_ref (event->any.window); - if (((event->any.type == GDK_ENTER_NOTIFY) || - (event->any.type == GDK_LEAVE_NOTIFY)) && - (event->crossing.subwindow != NULL)) - gdk_window_ref (event->crossing.subwindow); - } - else - { - /* Mark this event as having no resources to be freed */ - event->any.window = NULL; - event->any.type = GDK_NOTHING; - } - - if (window) - gdk_window_unref (window); - - return return_val; -} - -GdkFilterReturn -gdk_wm_protocols_filter (GdkXEvent *xev, - GdkEvent *event, - gpointer data) -{ - XEvent *xevent = (XEvent *)xev; - - if ((Atom) xevent->xclient.data.l[0] == gdk_wm_delete_window) - { - /* The delete window request specifies a window - * to delete. We don't actually destroy the - * window because "it is only a request". (The - * window might contain vital data that the - * program does not want destroyed). Instead - * the event is passed along to the program, - * which should then destroy the window. - */ - GDK_NOTE (EVENTS, - g_message ("delete window:\t\twindow: %ld", - xevent->xclient.window - base_id)); - - event->any.type = GDK_DELETE; - - return GDK_FILTER_TRANSLATE; - } - else if ((Atom) xevent->xclient.data.l[0] == gdk_wm_take_focus) - { - } - - return GDK_FILTER_REMOVE; -} - -#if 0 -static Bool -gdk_event_get_type (Display *display, - XEvent *xevent, - XPointer arg) -{ - GdkEvent event; - GdkPredicate *pred; - - if (gdk_event_translate (&event, xevent)) - { - pred = (GdkPredicate*) arg; - return (* pred->func) (&event, pred->data); - } - - return FALSE; -} -#endif - -static void -gdk_synthesize_click (GdkEvent *event, - gint nclicks) -{ - GdkEvent temp_event; - - g_return_if_fail (event != NULL); - - temp_event = *event; - temp_event.type = (nclicks == 2) ? GDK_2BUTTON_PRESS : GDK_3BUTTON_PRESS; - - gdk_event_put (&temp_event); -} - /* *-------------------------------------------------------------- * gdk_exit_func @@ -3115,88 +1060,50 @@ gdk_event_send_client_message (GdkEvent *event, guint32 xid) return gdk_send_xevent (xid, False, NoEventMask, &sev); } -/* Sends a ClientMessage to all toplevel client windows */ -gboolean -gdk_event_send_client_message_to_all_recurse (XEvent *xev, - guint32 xid, - guint level) +static RETSIGTYPE +gdk_signal (int sig_num) { - static GdkAtom wm_state_atom = GDK_NONE; - - Atom type = None; - int format; - unsigned long nitems, after; - unsigned char *data; + static int caught_fatal_sig = 0; + char *sig; - Window *ret_children, ret_root, ret_parent; - unsigned int ret_nchildren; - int i; + if (caught_fatal_sig) + kill (getpid (), sig_num); + caught_fatal_sig = 1; - gboolean send = FALSE; - gboolean found = FALSE; - - if (!wm_state_atom) - wm_state_atom = gdk_atom_intern ("WM_STATE", FALSE); - - gdk_error_code = 0; - XGetWindowProperty (gdk_display, xid, wm_state_atom, 0, 0, False, AnyPropertyType, - &type, &format, &nitems, &after, &data); - - if (gdk_error_code) - { - gdk_error_code = 0; - return FALSE; - } - - if (type) - { - send = TRUE; - XFree (data); - } - else + switch (sig_num) { - /* OK, we're all set, now let's find some windows to send this to */ - if (XQueryTree(gdk_display, xid, &ret_root, &ret_parent, - &ret_children, &ret_nchildren) != True) - return FALSE; - - if (gdk_error_code) - return FALSE; - - for(i = 0; i < ret_nchildren; i++) - if (gdk_event_send_client_message_to_all_recurse(xev, ret_children[i], level + 1)) - found = TRUE; - - XFree(ret_children); - } - - if (send || (!found && (level == 1))) - { - xev->xclient.window = xid; - gdk_send_xevent (xid, False, NoEventMask, xev); + case SIGHUP: + sig = "sighup"; + break; + case SIGINT: + sig = "sigint"; + break; + case SIGQUIT: + sig = "sigquit"; + break; + case SIGBUS: + sig = "sigbus"; + break; + case SIGSEGV: + sig = "sigsegv"; + break; + case SIGPIPE: + sig = "sigpipe"; + break; + case SIGTERM: + sig = "sigterm"; + break; + default: + sig = "unknown signal"; + break; } - - return (send || found); -} - -void -gdk_event_send_clientmessage_toall (GdkEvent *event) -{ - XEvent sev; - gint old_warnings = gdk_error_warnings; - - g_return_if_fail(event != NULL); - /* Set up our event to send, with the exception of its target window */ - sev.xclient.type = ClientMessage; - sev.xclient.display = gdk_display; - sev.xclient.format = event->client.data_format; - memcpy(&sev.xclient.data, &event->client.data, sizeof(sev.xclient.data)); - sev.xclient.message_type = event->client.message_type; - - gdk_event_send_client_message_to_all_recurse(&sev, gdk_root_window, 0); - - gdk_error_warnings = old_warnings; + g_message ("\n** ERROR **: %s caught", sig); +#ifdef G_ENABLE_DEBUG + abort (); +#else /* !G_ENABLE_DEBUG */ + gdk_exit (1); +#endif /* !G_ENABLE_DEBUG */ } gchar * diff --git a/gdk/x11/gdkwindow-x11.c b/gdk/x11/gdkwindow-x11.c index 72a56d8584..8e684c614e 100644 --- a/gdk/x11/gdkwindow-x11.c +++ b/gdk/x11/gdkwindow-x11.c @@ -33,7 +33,7 @@ #include <X11/extensions/shape.h> #endif -const int event_mask_table[20] = +const int gdk_event_mask_table[20] = { ExposureMask, PointerMotionMask, @@ -56,7 +56,7 @@ const int event_mask_table[20] = 0, /* PROXIMTY_OUT */ SubstructureNotifyMask }; -const int nevent_masks = sizeof(event_mask_table)/sizeof(int); +const int gdk_nevent_masks = sizeof(gdk_event_mask_table)/sizeof(int); static gboolean gdk_window_have_shape_ext (void); @@ -299,10 +299,10 @@ gdk_window_new (GdkWindow *parent, xvisual = ((GdkVisualPrivate*) visual)->xvisual; xattributes.event_mask = StructureNotifyMask; - for (i = 0; i < nevent_masks; i++) + for (i = 0; i < gdk_nevent_masks; i++) { if (attributes->event_mask & (1 << (i + 1))) - xattributes.event_mask |= event_mask_table[i]; + xattributes.event_mask |= gdk_event_mask_table[i]; } if (xattributes.event_mask) @@ -1703,9 +1703,9 @@ gdk_window_get_events (GdkWindow *window) &attrs); event_mask = 0; - for (i = 0; i < nevent_masks; i++) + for (i = 0; i < gdk_nevent_masks; i++) { - if (attrs.your_event_mask & event_mask_table[i]) + if (attrs.your_event_mask & gdk_event_mask_table[i]) event_mask |= 1 << (i + 1); } @@ -1727,10 +1727,10 @@ gdk_window_set_events (GdkWindow *window, return; xevent_mask = StructureNotifyMask; - for (i = 0; i < nevent_masks; i++) + for (i = 0; i < gdk_nevent_masks; i++) { if (event_mask & (1 << (i + 1))) - xevent_mask |= event_mask_table[i]; + xevent_mask |= gdk_event_mask_table[i]; } XSelectInput (gdk_display, private->xwindow, diff --git a/gtk/Makefile.am b/gtk/Makefile.am index 41d0725ac3..ef743f9f14 100644 --- a/gtk/Makefile.am +++ b/gtk/Makefile.am @@ -353,7 +353,8 @@ INCLUDES = \ @GLIB_CFLAGS@ \ @x_cflags@ -noinst_PROGRAMS = testgtk testinput testselection testthreads testrgb testdnd simple +noinst_PROGRAMS = testgtk testinput testselection testrgb testdnd simple +# testthreads DEPS = \ libgtk.la \ @@ -369,7 +370,7 @@ LDADDS = \ testgtk_DEPENDENCIES = $(DEPS) testinput_DEPENDENCIES = $(DEPS) -testthreads_DEPENDENCIES = $(DEPS) +#testthreads_DEPENDENCIES = $(DEPS) testselection_DEPENDENCIES = $(DEPS) testrgb_DEPENDENCIES = $(DEPS) testdnd_DEPENDENCIES = $(DEPS) @@ -377,7 +378,7 @@ simple_DEPENDENCIES = $(DEPS) testgtk_LDADD = $(LDADDS) testinput_LDADD = $(LDADDS) -testthreads_LDADD = $(LDADDS) +#testthreads_LDADD = $(LDADDS) testselection_LDADD = $(LDADDS) testrgb_LDADD = $(LDADDS) testdnd_LDADD = $(LDADDS) diff --git a/gtk/gtkaccellabel.c b/gtk/gtkaccellabel.c index e546d4c0b6..be6650dadb 100644 --- a/gtk/gtkaccellabel.c +++ b/gtk/gtkaccellabel.c @@ -24,6 +24,7 @@ #include "gtkmain.h" #include "gtksignal.h" #include "gtkaccellabel.h" +#include "gtkprivate.h" enum { @@ -45,6 +46,7 @@ static void gtk_accel_label_size_request (GtkWidget *widget, GtkRequisition *requisition); static gint gtk_accel_label_expose_event (GtkWidget *widget, GdkEventExpose *event); +static gboolean gtk_accel_label_refetch_idle (GtkAccelLabel *accel_label); static GtkAccelLabelClass *accel_label_class = NULL; static GtkLabelClass *parent_class = NULL; @@ -304,7 +306,7 @@ gtk_accel_label_queue_refetch (GtkAccelLabel *accel_label) if (accel_label->queue_id == 0) accel_label->queue_id = gtk_idle_add_priority (GTK_PRIORITY_HIGH - 2, - (GtkFunction) gtk_accel_label_refetch, + (GtkFunction) gtk_accel_label_refetch_idle, accel_label); } @@ -347,6 +349,18 @@ gtk_accel_label_set_accel_widget (GtkAccelLabel *accel_label, } } +static gboolean +gtk_accel_label_refetch_idle (GtkAccelLabel *accel_label) +{ + gboolean retval; + + GTK_THREADS_ENTER; + retval = gtk_accel_label_refetch (accel_label); + GTK_THREADS_LEAVE; + + return retval; +} + gboolean gtk_accel_label_refetch (GtkAccelLabel *accel_label) { diff --git a/gtk/gtkclist.c b/gtk/gtkclist.c index 6b5c1e075e..caf8a6895d 100644 --- a/gtk/gtkclist.c +++ b/gtk/gtkclist.c @@ -23,6 +23,7 @@ #include "gtkmain.h" #include "gtkclist.h" #include "gtkbindings.h" +#include "gtkprivate.h" #include <gdk/gdkkeysyms.h> /* the number rows memchunk expands at a time */ @@ -5041,7 +5042,7 @@ horizontal_timeout (GtkCList *clist) GdkEventMotion event; GdkModifierType mask; - g_return_val_if_fail (GTK_IS_CLIST (clist), FALSE); + GTK_THREADS_ENTER; clist->htimer = 0; gdk_window_get_pointer (clist->clist_window, &x, &y, &mask); @@ -5053,6 +5054,8 @@ horizontal_timeout (GtkCList *clist) gtk_clist_motion (GTK_WIDGET (clist), &event); + GTK_THREADS_LEAVE; + return FALSE; } @@ -5063,7 +5066,7 @@ vertical_timeout (GtkCList *clist) GdkEventMotion event; GdkModifierType mask; - g_return_val_if_fail (GTK_IS_CLIST (clist), FALSE); + GTK_THREADS_ENTER; clist->vtimer = 0; gdk_window_get_pointer (clist->clist_window, &x, &y, &mask); @@ -5075,6 +5078,8 @@ vertical_timeout (GtkCList *clist) gtk_clist_motion (GTK_WIDGET (clist), &event); + GTK_THREADS_LEAVE; + return FALSE; } diff --git a/gtk/gtkcolorsel.c b/gtk/gtkcolorsel.c index 894f3b86db..a4f7b38e5d 100644 --- a/gtk/gtkcolorsel.c +++ b/gtk/gtkcolorsel.c @@ -24,6 +24,7 @@ #include "gtkdrawwindow.h" #include "gtkhbbox.h" #include "gtkdnd.h" +#include "gtkprivate.h" #include "gtkselection.h" /* @@ -1025,11 +1026,15 @@ static gint gtk_color_selection_value_timeout (GtkColorSelection *colorsel) { gint x, y; - + + GTK_THREADS_ENTER; + gdk_window_get_pointer (colorsel->value_area->window, &x, &y, NULL); gtk_color_selection_update_value (colorsel, y); gtk_color_selection_color_changed (colorsel); + GTK_THREADS_LEAVE; + return (TRUE); } diff --git a/gtk/gtkcombo.c b/gtk/gtkcombo.c index f26f0a59cb..dceffd2f91 100644 --- a/gtk/gtkcombo.c +++ b/gtk/gtkcombo.c @@ -28,6 +28,7 @@ #include "gtklistitem.h" #include "gtkscrolledwindow.h" #include "gtkmain.h" +#include "gtkprivate.h" #include "gtksignal.h" #include "gtkwindow.h" #include "gdk/gdkkeysyms.h" @@ -235,7 +236,11 @@ static gint gtk_combo_focus_idle (GtkCombo * combo) { if (combo) - gtk_widget_grab_focus (combo->entry); + { + GTK_THREADS_ENTER; + gtk_widget_grab_focus (combo->entry); + GTK_THREADS_LEAVE; + } return FALSE; } diff --git a/gtk/gtkcontainer.c b/gtk/gtkcontainer.c index c3576afd5b..bbb3953a15 100644 --- a/gtk/gtkcontainer.c +++ b/gtk/gtkcontainer.c @@ -811,11 +811,13 @@ gtk_container_get_resize_container (GtkContainer *container) static gboolean gtk_container_idle_sizer (gpointer data) { + GTK_THREADS_ENTER; + /* we may be invoked with a container_resize_queue of NULL, because * queue_resize could have been adding an extra idle function while * the queue still got processed. we better just ignore such case * than trying to explicitely work around them with some extra flags, - * sine it doesn't cause any actual harm. + * since it doesn't cause any actual harm. */ while (container_resize_queue) { @@ -830,6 +832,8 @@ gtk_container_idle_sizer (gpointer data) GTK_PRIVATE_UNSET_FLAG (widget, GTK_RESIZE_PENDING); gtk_container_check_resize (GTK_CONTAINER (widget)); } + + GTK_THREADS_LEAVE; return FALSE; } diff --git a/gtk/gtkdnd.c b/gtk/gtkdnd.c index fd3b551e8b..a3f693b3e4 100644 --- a/gtk/gtkdnd.c +++ b/gtk/gtkdnd.c @@ -22,6 +22,7 @@ #include "gtkdnd.h" #include "gtkinvisible.h" #include "gtkmain.h" +#include "gtkprivate.h" #include "gtksignal.h" #include "gtkdrawwindow.h" @@ -2268,13 +2269,16 @@ gtk_drag_anim_timeout (gpointer data) { GtkDragAnim *anim = data; gint x, y; + gboolean retval; + + GTK_THREADS_ENTER; if (anim->step == anim->n_steps) { gtk_drag_source_info_destroy (anim->info); g_free (anim); - return FALSE; + retval = FALSE; } else { @@ -2287,8 +2291,12 @@ gtk_drag_anim_timeout (gpointer data) anim->step++; - return TRUE; + retval = TRUE; } + + GTK_THREADS_LEAVE; + + return retval; } static void diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c index 76e6d5b7b4..c77b15632c 100644 --- a/gtk/gtkentry.c +++ b/gtk/gtkentry.c @@ -22,6 +22,7 @@ #include "gdk/gdki18n.h" #include "gtkentry.h" #include "gtkmain.h" +#include "gtkprivate.h" #include "gtkselection.h" #include "gtksignal.h" #include "gtkstyle.h" @@ -1480,12 +1481,14 @@ gtk_entry_timer (gpointer data) { GtkEntry *entry; - g_return_val_if_fail (data != NULL, FALSE); + GTK_THREADS_ENTER; entry = GTK_ENTRY (data); entry->timer = 0; gtk_entry_draw_text (entry); + GTK_THREADS_LEAVE; + return FALSE; } diff --git a/gtk/gtklist.c b/gtk/gtklist.c index 18291954b0..ce004f3e8e 100644 --- a/gtk/gtklist.c +++ b/gtk/gtklist.c @@ -19,6 +19,7 @@ #include "gtklist.h" #include "gtklistitem.h" #include "gtkmain.h" +#include "gtkprivate.h" #include "gtksignal.h" #include "gtklabel.h" @@ -2308,7 +2309,7 @@ gtk_list_horizontal_timeout (GtkWidget *list) GdkEventMotion event; GdkModifierType mask; - g_return_val_if_fail (GTK_IS_LIST (list), FALSE); + GTK_THREADS_ENTER; GTK_LIST (list)->htimer = 0; gdk_window_get_pointer (list->window, &x, &y, &mask); @@ -2320,6 +2321,8 @@ gtk_list_horizontal_timeout (GtkWidget *list) gtk_list_motion_notify (list, &event); + GTK_THREADS_LEAVE; + return FALSE; } @@ -2331,7 +2334,7 @@ gtk_list_vertical_timeout (GtkWidget *list) GdkEventMotion event; GdkModifierType mask; - g_return_val_if_fail (GTK_IS_LIST (list), FALSE); + GTK_THREADS_ENTER; GTK_LIST (list)->vtimer = 0; gdk_window_get_pointer (list->window, &x, &y, &mask); @@ -2343,6 +2346,8 @@ gtk_list_vertical_timeout (GtkWidget *list) gtk_list_motion_notify (list, &event); + GTK_THREADS_LEAVE; + return FALSE; } diff --git a/gtk/gtkmain.c b/gtk/gtkmain.c index eb5949707e..918e63160c 100644 --- a/gtk/gtkmain.c +++ b/gtk/gtkmain.c @@ -43,14 +43,13 @@ #include "gtkdebug.h" #include "gtkintl.h" +extern gboolean gdk_using_threads; /* Private type definitions */ typedef struct _GtkInitFunction GtkInitFunction; typedef struct _GtkQuitFunction GtkQuitFunction; -typedef struct _GtkTimeoutFunction GtkTimeoutFunction; -typedef struct _GtkIdleHook GtkIdleHook; -typedef struct _GtkInputFunction GtkInputFunction; +typedef struct _GtkClosure GtkClosure; typedef struct _GtkKeySnooperData GtkKeySnooperData; struct _GtkInitFunction @@ -69,37 +68,13 @@ struct _GtkQuitFunction GtkDestroyNotify destroy; }; -struct _GtkTimeoutFunction +struct _GtkClosure { - guint tag; - guint32 start; - guint32 interval; - guint32 originterval; - GtkFunction function; GtkCallbackMarshal marshal; gpointer data; GtkDestroyNotify destroy; }; -enum -{ - GTK_HOOK_MARSHAL = 1 << (G_HOOK_FLAG_USER_SHIFT) -}; - -struct _GtkIdleHook -{ - GHook hook; - gint priority; -}; -#define GTK_IDLE_HOOK(hook) ((GtkIdleHook*) hook) - -struct _GtkInputFunction -{ - GtkCallbackMarshal callback; - gpointer data; - GtkDestroyNotify destroy; -}; - struct _GtkKeySnooperData { GtkKeySnoopFunc func; @@ -107,21 +82,20 @@ struct _GtkKeySnooperData guint id; }; -static void gtk_exit_func (void); -static void gtk_invoke_hook (GHookList *hook_list, - GHook *hook); -static void gtk_handle_idles (void); -static gboolean gtk_finish_idles (void); +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 gint gtk_invoke_key_snoopers (GtkWidget *grab_widget, GdkEvent *event); -static void gtk_handle_timeouts (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); @@ -129,26 +103,18 @@ static void gtk_message (gchar *str); static void gtk_print (gchar *str); #endif -static gint gtk_timeout_remove_from_list (GList **list, - guint tag, - gint remove_link); - -static gint gtk_timeout_compare (gconstpointer a, - gconstpointer b); - - const guint gtk_major_version = GTK_MAJOR_VERSION; const guint gtk_minor_version = GTK_MINOR_VERSION; const guint gtk_micro_version = GTK_MICRO_VERSION; const guint gtk_binary_age = GTK_BINARY_AGE; const guint gtk_interface_age = GTK_INTERFACE_AGE; -static gboolean iteration_done = FALSE; static guint 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. */ @@ -156,53 +122,6 @@ static GList *init_functions = NULL; /* A list of init functions. */ 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. */ -/* Prioritized idle callbacks */ -static GHookList idle_hooks = { 0 }; -static GHook *last_idle = NULL; - -/* The timeouts that are currently being processed - * by gtk_handle_current_timeouts - */ -static GList *current_timeouts = NULL; - -/* A stack of timeouts that is currently being executed - */ -static GList *running_timeouts = NULL; - -static GMemChunk *timeout_mem_chunk = NULL; static GMemChunk *quit_mem_chunk = NULL; static GSList *key_snoopers = NULL; @@ -216,6 +135,8 @@ static GdkColormap *gtk_colormap; /* The colormap to be used in creating new guint gtk_debug_flags = 0; /* Global GTK debug flag */ +GMutex *gtk_threads_mutex = NULL; /* Global GTK lock */ + #ifdef G_ENABLE_DEBUG static const GDebugKey gtk_debug_keys[] = { {"objects", GTK_DEBUG_OBJECTS}, @@ -260,6 +181,15 @@ gtk_init (int *argc, if (gtk_initialized) return; + /* There is some argument for putting this in a separate + * function ... but I don't think that it is much + * of a restriction to require that GTK+ be used + * single threaded until gtk_init(). + */ + + if (g_thread_supported) + gtk_threads_mutex = g_mutex_new (); + #if 0 g_set_error_handler (gtk_error); g_set_warning_handler (gtk_warning); @@ -271,6 +201,8 @@ gtk_init (int *argc, * parameters as they contain information that GDK uses */ gdk_init (argc, argv); + + gdk_event_handler_set ((GdkEventFunc *)gtk_main_do_event, NULL, NULL); #ifdef G_ENABLE_DEBUG env_string = getenv ("GTK_DEBUG"); @@ -507,8 +439,10 @@ gtk_main (void) GList *tmp_list; GList *functions; GtkInitFunction *init; - int old_done; - + + GMainLoop *loop; + GSList *tmp_node; + gtk_main_loop_level++; tmp_list = functions = init_functions; @@ -524,10 +458,18 @@ gtk_main (void) } g_list_free (functions); - old_done = iteration_done; - while (!gtk_main_iteration ()) - ; - iteration_done = old_done; + loop = g_main_new (); + main_loops = g_slist_prepend (main_loops, loop); + + GTK_THREADS_LEAVE; + g_main_run (loop); + GTK_THREADS_ENTER; + + g_main_destroy (loop); + + tmp_node = main_loops; + main_loops = g_slist_remove_link (main_loops, main_loops); + g_slist_free_1 (tmp_node); if (quit_functions) { @@ -575,310 +517,211 @@ gtk_main_level (void) void gtk_main_quit (void) { - iteration_done = TRUE; + 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 += last_idle != NULL; - result += current_timeouts != NULL; - - if (!result) - { - GHook *hook; - - hook = g_hook_first_valid (&idle_hooks, FALSE); - - result += hook && GTK_IDLE_HOOK (hook)->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); + return g_main_iteration (TRUE); } -gint +gint gtk_main_iteration_do (gboolean blocking) { + return g_main_iteration (blocking); +} + +static 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_get (); - 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)) + { + gdk_event_free (next_event); + next_event = NULL; + + return; + } + - return iteration_done; - } - if (last_idle && gtk_finish_idles ()) + if (next_event) + gdk_event_put (next_event); + next_event = NULL; + + /* 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) { - 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; + } + else + { + 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. + /* 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) - { - /* 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); - - gdk_event_free (event); - - goto event_handling_done; - } + 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; - /* Push the event onto a stack of current events for - * gtk_current_event_get(). - */ - current_events = g_list_prepend (current_events, event); + 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; - /* If there is a grab in effect... - */ - if (grabs) + 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_PRESS: + case GDK_2BUTTON_PRESS: + case GDK_3BUTTON_PRESS: + 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. - * - * Drag events are also not redirected, since it isn't - * clear what the semantics of that would be. - */ - 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_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: - 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; - - 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 (GTK_WIDGET_IS_SENSITIVE (grab_widget)) + gtk_widget_event (grab_widget, event); + break; - tmp_list = current_events; - current_events = g_list_remove_link (current_events, tmp_list); - g_list_free_1 (tmp_list); - - gdk_event_free (event); - } - else - { - if (gdk_events_pending() == 0) - gtk_handle_idles (); + case GDK_DRAG_STATUS: + case GDK_DROP_FINISHED: + gtk_drag_source_handle_event (event_widget, event); + break; + case GDK_DRAG_ENTER: + case GDK_DRAG_LEAVE: + case GDK_DRAG_MOTION: + case GDK_DROP_START: + gtk_drag_dest_handle_event (event_widget, event); + break; } -event_handling_done: - - /* Handle timeout functions that may have expired. - */ - gtk_handle_timeouts (); - - 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 @@ -1001,119 +844,6 @@ gtk_invoke_key_snoopers (GtkWidget *grab_widget, } 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) -{ - g_message ("gtk_timeout_add_interp() is deprecated"); - 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; -} - -guint gtk_quit_add_full (guint main_level, GtkFunction function, GtkCallbackMarshal marshal, @@ -1143,291 +873,6 @@ gtk_quit_add_full (guint main_level, return quitf->id; } -gint -gtk_idle_compare (GHook *new_g_hook, - GHook *g_sibling) -{ - GtkIdleHook *new_hook = GTK_IDLE_HOOK (new_g_hook); - GtkIdleHook *sibling = GTK_IDLE_HOOK (g_sibling); - - /* We add an extra +1 to the comparision result to make sure - * that we get inserted at the end of the list of hooks with - * the same priority. - */ - return new_hook->priority - sibling->priority + 1; -} - -guint -gtk_idle_add_full (gint priority, - GtkFunction function, - GtkCallbackMarshal marshal, - gpointer data, - GtkDestroyNotify destroy) -{ - GHook *hook; - GtkIdleHook *ihook; - - if (function) - g_return_val_if_fail (marshal == NULL, 0); - else - g_return_val_if_fail (marshal != NULL, 0); - - if (!idle_hooks.seq_id) - g_hook_list_init (&idle_hooks, sizeof (GtkIdleHook)); - - hook = g_hook_alloc (&idle_hooks); - ihook = GTK_IDLE_HOOK (hook); - hook->data = data; - if (marshal) - { - hook->flags |= GTK_HOOK_MARSHAL; - hook->func = marshal; - } - else - hook->func = function; - hook->destroy = destroy; - ihook->priority = priority; - - /* If we are adding the first idle function, possibly wake up - * the main thread out of its select(). - */ - if (!g_hook_first_valid (&idle_hooks, TRUE)) - gdk_threads_wake (); - - g_hook_insert_sorted (&idle_hooks, hook, gtk_idle_compare); - - return hook->hook_id; -} - -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); -} - -guint -gtk_idle_add_interp (GtkCallbackMarshal marshal, - gpointer data, - GtkDestroyNotify destroy) -{ - g_message ("gtk_idle_add_interp() is deprecated"); - return gtk_idle_add_full (GTK_PRIORITY_DEFAULT, NULL, marshal, data, destroy); -} - -void -gtk_idle_remove (guint tag) -{ - g_return_if_fail (tag > 0); - - if (!g_hook_destroy (&idle_hooks, tag)) - g_warning ("gtk_idle_remove(%d): no such idle function", tag); -} - -void -gtk_idle_remove_by_data (gpointer data) -{ - GHook *hook; - - hook = g_hook_find_data (&idle_hooks, TRUE, data); - if (hook) - g_hook_destroy_link (&idle_hooks, hook); - else - g_warning ("gtk_idle_remove_by_data(%p): no such idle function", data); -} - -static gboolean -gtk_finish_idles (void) -{ - gboolean idles_called; - - idles_called = FALSE; - while (last_idle) - { - GHook *hook; - - hook = g_hook_next_valid (last_idle, FALSE); - - if (!hook || GTK_IDLE_HOOK (hook)->priority != GTK_IDLE_HOOK (last_idle)->priority) - { - g_hook_unref (&idle_hooks, last_idle); - last_idle = NULL; - } - else - { - g_hook_unref (&idle_hooks, last_idle); - last_idle = hook; - g_hook_ref (&idle_hooks, last_idle); - - idles_called = TRUE; - gtk_invoke_hook (&idle_hooks, last_idle); - } - } - - return idles_called; -} - -static void -gtk_handle_idles (void) -{ - GHook *hook; - - /* Caller must already have called gtk_finish_idles() if necessary - */ - g_assert (last_idle == NULL); - - hook = g_hook_first_valid (&idle_hooks, FALSE); - - if (hook) - { - last_idle = hook; - g_hook_ref (&idle_hooks, last_idle); - - gtk_invoke_hook (&idle_hooks, last_idle); - - gtk_finish_idles (); - } -} - -static void -gtk_invoke_hook (GHookList *hook_list, - GHook *hook) -{ - gboolean keep_alive; - - if (hook->flags & GTK_HOOK_MARSHAL) - { - GtkArg args[1]; - register GtkCallbackMarshal marshal; - - keep_alive = FALSE; - args[0].name = NULL; - args[0].type = GTK_TYPE_BOOL; - GTK_VALUE_POINTER (args[0]) = &keep_alive; - marshal = hook->func; - marshal (NULL, hook->data, 0, args); - } - else - { - register GtkFunction func; - - func = hook->func; - keep_alive = func (hook->data); - } - if (!keep_alive) - g_hook_destroy_link (hook_list, hook); -} - -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 void gtk_quit_destroy (GtkQuitFunction *quitf) { @@ -1521,30 +966,112 @@ gtk_quit_remove_by_data (gpointer data) } } -static void -gtk_invoke_input_function (GtkInputFunction *input, - gint source, - GdkInputCondition condition) +guint +gtk_timeout_add_full (guint32 interval, + 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; + + closure = g_new (GtkClosure, 1); + closure->marshal = marshal; + closure->data = data; + closure->destroy = destroy; - input->callback (NULL, input->data, 2, args); + 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); } -static void -gtk_destroy_input_function (GtkInputFunction *input) +guint +gtk_timeout_add (guint32 interval, + GtkFunction function, + gpointer data) +{ + return g_timeout_add_full (0, interval, function, 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) +{ + g_source_remove (tag); +} + +guint +gtk_idle_add_full (gint priority, + GtkFunction function, + GtkCallbackMarshal marshal, + gpointer data, + GtkDestroyNotify 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 (GTK_PRIORITY_DEFAULT, function, data, NULL); +} + +guint +gtk_idle_add_priority (gint priority, + GtkFunction function, + gpointer data) +{ + return g_idle_add_full (priority, function, data, NULL); +} + +guint +gtk_idle_add_interp (GtkCallbackMarshal marshal, + gpointer data, + GtkDestroyNotify destroy) +{ + return gtk_idle_add_full (GTK_PRIORITY_DEFAULT, NULL, marshal, data, destroy); +} + +void +gtk_idle_remove (guint tag) +{ + g_source_remove (tag); +} + +void +gtk_idle_remove_by_data (gpointer data) { - if (input->destroy) - (input->destroy) (input->data); - g_free (input); + g_source_remove_by_user_data (data); } guint @@ -1557,18 +1084,18 @@ gtk_input_add_full (gint source, { 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); @@ -1577,7 +1104,50 @@ gtk_input_add_full (gint source, 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; +} + +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 * @@ -1612,30 +1182,6 @@ gtk_exit_func (void) } -/* 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_quit_invoke_function (GtkQuitFunction *quitf) { @@ -1657,29 +1203,6 @@ gtk_quit_invoke_function (GtkQuitFunction *quitf) } static void -gtk_handle_timer (void) -{ - GtkTimeoutFunction *timeoutf; - - if (g_hook_first_valid (&idle_hooks, FALSE)) - { - 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 gtk_propagate_event (GtkWidget *widget, GdkEvent *event) { @@ -1726,6 +1249,17 @@ gtk_propagate_event (GtkWidget *widget, } } +void +gtk_threads_enter () +{ + GTK_THREADS_ENTER; +} + +void +gtk_threads_leave () +{ + GTK_THREADS_LEAVE; +} #if 0 static void diff --git a/gtk/gtkmain.h b/gtk/gtkmain.h index 28ab996b84..8856716a59 100644 --- a/gtk/gtkmain.h +++ b/gtk/gtkmain.h @@ -30,7 +30,7 @@ extern "C" { #define GTK_PRIORITY_HIGH -20 #define GTK_PRIORITY_INTERNAL -10 -#define GTK_PRIORITY_DEFAULT 0 +#define GTK_PRIORITY_DEFAULT -5 #define GTK_PRIORITY_LOW 10 typedef void (*GtkModuleInitFunc) (gint *argc, @@ -58,6 +58,13 @@ void gtk_init (int *argc, void gtk_exit (gint error_code); gchar* gtk_set_locale (void); gint gtk_events_pending (void); + +/* The following is the event func GTK+ registers with GDK + * we expose it mainly to allow filtering of events between + * GDK and GTK+. + */ +void gtk_main_do_event (GdkEvent *event); + void gtk_main (void); guint gtk_main_level (void); void gtk_main_quit (void); @@ -122,8 +129,10 @@ guint gtk_key_snooper_install (GtkKeySnoopFunc snooper, void gtk_key_snooper_remove (guint snooper_handler_id); GdkEvent* gtk_get_current_event (void); -GtkWidget* gtk_get_event_widget (GdkEvent *event); +GtkWidget* gtk_get_event_widget (GdkEvent *event); +void gtk_threads_enter (void); +void gtk_threads_leave (void); /* deprecated */ guint gtk_idle_add_interp (GtkCallbackMarshal marshal, diff --git a/gtk/gtkmenuitem.c b/gtk/gtkmenuitem.c index 3f6e3462fb..bfafefc032 100644 --- a/gtk/gtkmenuitem.c +++ b/gtk/gtkmenuitem.c @@ -19,6 +19,7 @@ #include <string.h> #include "gtkaccellabel.h" #include "gtkmain.h" +#include "gtkprivate.h" #include "gtkmenu.h" #include "gtkmenubar.h" #include "gtkmenuitem.h" @@ -620,6 +621,8 @@ gtk_menu_item_select_timeout (gpointer data) { GtkMenuItem *menu_item; + GTK_THREADS_ENTER; + menu_item = GTK_MENU_ITEM (data); menu_item->timer = 0; @@ -641,6 +644,8 @@ gtk_menu_item_select_timeout (gpointer data) gtk_menu_shell_select_item (submenu, submenu->children->data); } + GTK_THREADS_LEAVE; + return FALSE; } diff --git a/gtk/gtknotebook.c b/gtk/gtknotebook.c index 1ab5da6f28..6a749f2d5a 100644 --- a/gtk/gtknotebook.c +++ b/gtk/gtknotebook.c @@ -19,6 +19,7 @@ #include "gtknotebook.h" #include "gtksignal.h" #include "gtkmain.h" +#include "gtkprivate.h" #include "gtkmenu.h" #include "gtkmenuitem.h" #include "gtklabel.h" @@ -1834,9 +1835,10 @@ gtk_notebook_focus_changed (GtkNotebook *notebook, static gint gtk_notebook_timer (GtkNotebook *notebook) { - g_return_val_if_fail (notebook != NULL, FALSE); - g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), FALSE); + gboolean retval = FALSE; + GTK_THREADS_ENTER; + if (notebook->timer) { if (notebook->click_child == GTK_ARROW_LEFT) @@ -1859,11 +1861,14 @@ gtk_notebook_timer (GtkNotebook *notebook) notebook->timer = gtk_timeout_add (NOTEBOOK_SCROLL_DELAY, (GtkFunction) gtk_notebook_timer, (gpointer) notebook); - return FALSE; } - return TRUE; + else + retval = TRUE; } - return FALSE; + + GTK_THREADS_LEAVE; + + return retval; } static gint diff --git a/gtk/gtkprivate.h b/gtk/gtkprivate.h index a71cd73161..17a7b3f872 100644 --- a/gtk/gtkprivate.h +++ b/gtk/gtkprivate.h @@ -60,6 +60,19 @@ typedef enum #define GTK_PRIVATE_SET_FLAG(wid,flag) G_STMT_START{ (GTK_PRIVATE_FLAGS (wid) |= (PRIVATE_ ## flag)); }G_STMT_END #define GTK_PRIVATE_UNSET_FLAG(wid,flag) G_STMT_START{ (GTK_PRIVATE_FLAGS (wid) &= ~(PRIVATE_ ## flag)); }G_STMT_END +/* Threading functions */ + +extern GMutex *gtk_threads_mutex; + +#define GTK_THREADS_ENTER G_STMT_START { \ + if (gtk_threads_mutex) \ + g_mutex_lock (gtk_threads_mutex); \ + } G_STMT_END +#define GTK_THREADS_LEAVE G_STMT_START { \ + if (gtk_threads_mutex) \ + g_mutex_unlock (gtk_threads_mutex); \ + } G_STMT_END + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/gtk/gtkrange.c b/gtk/gtkrange.c index 73bed02dde..485c58f7e1 100644 --- a/gtk/gtkrange.c +++ b/gtk/gtkrange.c @@ -19,6 +19,7 @@ #include <stdio.h> #include "gtkmain.h" #include "gtkrange.h" +#include "gtkprivate.h" #include "gtksignal.h" @@ -1236,8 +1237,7 @@ gtk_real_range_timer (GtkRange *range) { gint return_val; - g_return_val_if_fail (range != NULL, FALSE); - g_return_val_if_fail (GTK_IS_RANGE (range), FALSE); + GTK_THREADS_ENTER; return_val = TRUE; if (range->click_child == RANGE_CLASS (range)->slider) @@ -1258,7 +1258,10 @@ gtk_real_range_timer (GtkRange *range) (GtkFunction) RANGE_CLASS (range)->timer, (gpointer) range); else - return FALSE; + { + GTK_THREADS_LEAVE; + return FALSE; + } range->need_timer = FALSE; } @@ -1284,6 +1287,8 @@ gtk_real_range_timer (GtkRange *range) return_val = gtk_range_scroll (range, -1); } + GTK_THREADS_LEAVE; + return return_val; } diff --git a/gtk/gtkselection.c b/gtk/gtkselection.c index d9dc09b6fb..0b4ea6fa4c 100644 --- a/gtk/gtkselection.c +++ b/gtk/gtkselection.c @@ -49,6 +49,7 @@ #include <gdk/gdkx.h> /* we need this for gdk_window_lookup() */ #include "gtkmain.h" +#include "gtkprivate.h" #include "gtkselection.h" #include "gtksignal.h" @@ -1089,6 +1090,9 @@ static gint gtk_selection_incr_timeout (GtkIncrInfo *info) { GList *tmp_list; + gboolean retval; + + GTK_THREADS_ENTER; /* Determine if retrieval has finished by checking if it still in list of pending retrievals */ @@ -1116,14 +1120,18 @@ gtk_selection_incr_timeout (GtkIncrInfo *info) g_free (info); - return FALSE; /* remove timeout */ + retval = FALSE; /* remove timeout */ } else { info->idle_time++; - return TRUE; /* timeout will happen again */ + retval = TRUE; /* timeout will happen again */ } + + GTK_THREADS_LEAVE; + + return retval; } /************************************************************* @@ -1324,6 +1332,9 @@ static gint gtk_selection_retrieval_timeout (GtkRetrievalInfo *info) { GList *tmp_list; + gboolean retval; + + GTK_THREADS_ENTER; /* Determine if retrieval has finished by checking if it still in list of pending retrievals */ @@ -1349,15 +1360,18 @@ gtk_selection_retrieval_timeout (GtkRetrievalInfo *info) g_free (info->buffer); g_free (info); - return FALSE; /* remove timeout */ + retval = FALSE; /* remove timeout */ } else { info->idle_time++; - return TRUE; /* timeout will happen again */ + retval = TRUE; /* timeout will happen again */ } - + + GTK_THREADS_LEAVE; + + return retval; } /************************************************************* diff --git a/gtk/gtkspinbutton.c b/gtk/gtkspinbutton.c index 869a0f2656..58f69d616f 100644 --- a/gtk/gtkspinbutton.c +++ b/gtk/gtkspinbutton.c @@ -28,6 +28,7 @@ #include "gdk/gdkkeysyms.h" #include "gtkspinbutton.h" #include "gtkmain.h" +#include "gtkprivate.h" #include "gtksignal.h" @@ -907,8 +908,9 @@ gtk_spin_button_motion_notify (GtkWidget *widget, static gint gtk_spin_button_timer (GtkSpinButton *spin_button) { - g_return_val_if_fail (spin_button != NULL, FALSE); - g_return_val_if_fail (GTK_IS_SPIN_BUTTON (spin_button), FALSE); + gboolean retval = FALSE; + + GTK_THREADS_ENTER; if (spin_button->timer) { @@ -923,22 +925,27 @@ gtk_spin_button_timer (GtkSpinButton *spin_button) spin_button->timer = gtk_timeout_add (SPIN_BUTTON_TIMER_DELAY, (GtkFunction) gtk_spin_button_timer, (gpointer) spin_button); - return FALSE; } - else if (spin_button->climb_rate > 0.0 && spin_button->timer_step - < spin_button->adjustment->page_increment) + else { - if (spin_button->timer_calls < MAX_TIMER_CALLS) - spin_button->timer_calls++; - else + if (spin_button->climb_rate > 0.0 && spin_button->timer_step + < spin_button->adjustment->page_increment) { - spin_button->timer_calls = 0; - spin_button->timer_step += spin_button->climb_rate; + if (spin_button->timer_calls < MAX_TIMER_CALLS) + spin_button->timer_calls++; + else + { + spin_button->timer_calls = 0; + spin_button->timer_step += spin_button->climb_rate; + } } + retval = TRUE; } - return TRUE; } - return FALSE; + + GTK_THREADS_LEAVE; + + return retval; } static void diff --git a/gtk/gtktext.c b/gtk/gtktext.c index 0a993a2fd2..79a208a426 100644 --- a/gtk/gtktext.c +++ b/gtk/gtktext.c @@ -21,6 +21,7 @@ #include "gdk/gdkkeysyms.h" #include "gdk/gdki18n.h" #include "gtkmain.h" +#include "gtkprivate.h" #include "gtkselection.h" #include "gtksignal.h" #include "gtktext.h" @@ -1697,26 +1698,27 @@ gtk_text_scroll_timeout (gpointer data) { GtkText *text; GdkEventMotion event; - gint x, y; GdkModifierType mask; - g_return_val_if_fail (GTK_IS_TEXT (data), FALSE); - + GTK_THREADS_ENTER; + text = GTK_TEXT (data); text->timer = 0; gdk_window_get_pointer (text->text_area, &x, &y, &mask); - if (!(mask & (GDK_BUTTON1_MASK | GDK_BUTTON3_MASK))) - return FALSE; - - event.is_hint = 0; - event.x = x; - event.y = y; - event.state = mask; - - gtk_text_motion_notify (GTK_WIDGET (text), &event); + if (mask & (GDK_BUTTON1_MASK | GDK_BUTTON3_MASK)) + { + event.is_hint = 0; + event.x = x; + event.y = y; + event.state = mask; + + gtk_text_motion_notify (GTK_WIDGET (text), &event); + } + + GTK_THREADS_LEAVE; return FALSE; } diff --git a/gtk/gtktooltips.c b/gtk/gtktooltips.c index a1820d742a..22526e45c3 100644 --- a/gtk/gtktooltips.c +++ b/gtk/gtktooltips.c @@ -21,6 +21,7 @@ #include <stdio.h> #include "gtkmain.h" +#include "gtkprivate.h" #include "gtkwidget.h" #include "gtkdrawwindow.h" #include "gtksignal.h" @@ -493,10 +494,14 @@ gtk_tooltips_timeout (gpointer data) { GtkTooltips *tooltips = (GtkTooltips *) data; + GTK_THREADS_ENTER; + if (tooltips->active_tips_data != NULL && GTK_WIDGET_DRAWABLE (tooltips->active_tips_data->widget)) gtk_tooltips_draw_tips (tooltips); + GTK_THREADS_LEAVE; + return FALSE; } diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index 36f74ae355..4df977577f 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -1950,6 +1950,8 @@ gtk_widget_idle_draw (gpointer data) GSList *draw_data_list; GtkWidget *widget; + GTK_THREADS_ENTER; + /* Translate all draw requests to be allocation-relative */ widget_list = gtk_widget_redraw_queue; while (widget_list) @@ -2131,6 +2133,8 @@ gtk_widget_idle_draw (gpointer data) g_slist_free (gtk_widget_redraw_queue); gtk_widget_redraw_queue = NULL; + GTK_THREADS_LEAVE; + return FALSE; } diff --git a/gtk/gtkwidget.h b/gtk/gtkwidget.h index 295a29fc34..c944440d2a 100644 --- a/gtk/gtkwidget.h +++ b/gtk/gtkwidget.h @@ -49,7 +49,8 @@ typedef enum GTK_HAS_DEFAULT = 1 << 14, GTK_HAS_GRAB = 1 << 15, GTK_RC_STYLE = 1 << 16, - GTK_COMPOSITE_CHILD = 1 << 17 + GTK_COMPOSITE_CHILD = 1 << 17, + GTK_NO_REPARENT = 1 << 18 } GtkWidgetFlags; /* Macro for casting a pointer to a GtkWidget or GtkWidgetClass pointer. diff --git a/gtk/testthreads.c b/gtk/testthreads.c index 27e0753f31..c89ad58854 100644 --- a/gtk/testthreads.c +++ b/gtk/testthreads.c @@ -53,7 +53,7 @@ counter (void *data) GtkWidget *label; GtkWidget *button; - gdk_threads_enter(); + gtk_threads_enter(); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_title (GTK_WINDOW (window), name); @@ -83,7 +83,7 @@ counter (void *data) { sprintf(buffer, "%d", counter); gtk_label_set (GTK_LABEL (label), buffer); - gdk_threads_leave(); + gtk_threads_leave(); counter++; /* Give someone else a chance to get the lock next time. * Only necessary because we don't do anything else while @@ -91,7 +91,7 @@ counter (void *data) */ sleep(0); - gdk_threads_enter(); + gtk_threads_enter(); } gtk_widget_destroy (window); @@ -102,7 +102,7 @@ counter (void *data) gtk_main_quit(); pthread_mutex_unlock (&nthreads_mutex); - gdk_threads_leave(); + gtk_threads_leave(); return NULL; } @@ -115,7 +115,7 @@ main (int argc, char **argv) #ifdef USE_PTHREADS int i; - if (!gdk_threads_init()) + if (!gtk_threads_init()) { fprintf(stderr, "Could not initialize threads\n"); exit(1); @@ -141,9 +141,9 @@ main (int argc, char **argv) pthread_mutex_unlock (&nthreads_mutex); - gdk_threads_enter(); + gtk_threads_enter(); gtk_main(); - gdk_threads_leave(); + gtk_threads_leave(); fprintf(stderr, "Done\n"); #else /* !USE_PTHREADS */ fprintf (stderr, "GTK+ not compiled with threads support\n"); diff --git a/tests/testthreads.c b/tests/testthreads.c index 27e0753f31..c89ad58854 100644 --- a/tests/testthreads.c +++ b/tests/testthreads.c @@ -53,7 +53,7 @@ counter (void *data) GtkWidget *label; GtkWidget *button; - gdk_threads_enter(); + gtk_threads_enter(); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_title (GTK_WINDOW (window), name); @@ -83,7 +83,7 @@ counter (void *data) { sprintf(buffer, "%d", counter); gtk_label_set (GTK_LABEL (label), buffer); - gdk_threads_leave(); + gtk_threads_leave(); counter++; /* Give someone else a chance to get the lock next time. * Only necessary because we don't do anything else while @@ -91,7 +91,7 @@ counter (void *data) */ sleep(0); - gdk_threads_enter(); + gtk_threads_enter(); } gtk_widget_destroy (window); @@ -102,7 +102,7 @@ counter (void *data) gtk_main_quit(); pthread_mutex_unlock (&nthreads_mutex); - gdk_threads_leave(); + gtk_threads_leave(); return NULL; } @@ -115,7 +115,7 @@ main (int argc, char **argv) #ifdef USE_PTHREADS int i; - if (!gdk_threads_init()) + if (!gtk_threads_init()) { fprintf(stderr, "Could not initialize threads\n"); exit(1); @@ -141,9 +141,9 @@ main (int argc, char **argv) pthread_mutex_unlock (&nthreads_mutex); - gdk_threads_enter(); + gtk_threads_enter(); gtk_main(); - gdk_threads_leave(); + gtk_threads_leave(); fprintf(stderr, "Done\n"); #else /* !USE_PTHREADS */ fprintf (stderr, "GTK+ not compiled with threads support\n"); |