summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog40
-rw-r--r--ChangeLog.pre-2-040
-rw-r--r--ChangeLog.pre-2-1040
-rw-r--r--ChangeLog.pre-2-240
-rw-r--r--ChangeLog.pre-2-440
-rw-r--r--ChangeLog.pre-2-640
-rw-r--r--ChangeLog.pre-2-840
-rw-r--r--config.h.in5
-rw-r--r--configure.in37
-rw-r--r--docs/Changes-1.2.txt61
-rw-r--r--gdk/Makefile.am2
-rw-r--r--gdk/gdk.c2183
-rw-r--r--gdk/gdk.h18
-rw-r--r--gdk/gdkglobals.c8
-rw-r--r--gdk/gdkim.c8
-rw-r--r--gdk/gdkprivate.h7
-rw-r--r--gdk/gdkthreads.c68
-rw-r--r--gdk/gdktypes.h2
-rw-r--r--gdk/gdkwindow.c16
-rw-r--r--gdk/x11/gdkglobals-x11.c8
-rw-r--r--gdk/x11/gdkim-x11.c8
-rw-r--r--gdk/x11/gdkmain-x11.c2183
-rw-r--r--gdk/x11/gdkwindow-x11.c16
-rw-r--r--gtk/Makefile.am7
-rw-r--r--gtk/gtkaccellabel.c16
-rw-r--r--gtk/gtkclist.c9
-rw-r--r--gtk/gtkcolorsel.c7
-rw-r--r--gtk/gtkcombo.c7
-rw-r--r--gtk/gtkcontainer.c6
-rw-r--r--gtk/gtkdnd.c12
-rw-r--r--gtk/gtkentry.c5
-rw-r--r--gtk/gtklist.c9
-rw-r--r--gtk/gtkmain.c1196
-rw-r--r--gtk/gtkmain.h13
-rw-r--r--gtk/gtkmenuitem.c5
-rw-r--r--gtk/gtknotebook.c15
-rw-r--r--gtk/gtkprivate.h13
-rw-r--r--gtk/gtkrange.c11
-rw-r--r--gtk/gtkselection.c24
-rw-r--r--gtk/gtkspinbutton.c31
-rw-r--r--gtk/gtktext.c26
-rw-r--r--gtk/gtktooltips.c5
-rw-r--r--gtk/gtkwidget.c4
-rw-r--r--gtk/gtkwidget.h3
-rw-r--r--gtk/testthreads.c14
-rw-r--r--tests/testthreads.c14
46 files changed, 1033 insertions, 5329 deletions
diff --git a/ChangeLog b/ChangeLog
index d101dbb00a..992a64f6b3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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 \
diff --git a/gdk/gdk.c b/gdk/gdk.c
index 117f4534f8..efd926154b 100644
--- a/gdk/gdk.c
+++ b/gdk/gdk.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/gdk.h b/gdk/gdk.h
index 0127077fc2..62e4a1b3ac 100644
--- a/gdk/gdk.h
+++ b/gdk/gdk.h
@@ -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 (&current_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");