[gtk+/events-refactor: 503/1085] Merge branch 'master' into events-refactor
- From: Carlos Garnacho <carlosg src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gtk+/events-refactor: 503/1085] Merge branch 'master' into events-refactor
- Date: Tue, 29 Sep 2009 10:46:26 +0000 (UTC)
commit 37c3ec1dab8547d3124f930cb3479eb993d934d8
Merge: aaf92a2... 2de23ea...
Author: Carlos Garnacho <carlos lanedo com>
Date: Fri Jul 10 18:46:00 2009 +0100
Merge branch 'master' into events-refactor
Conflicts:
gdk/x11/gdkdisplay-x11.c
gdk/x11/gdkevents-x11.c
gdk/x11/gdkmain-x11.c
gdk/x11/gdkwindow-x11.c
NEWS | 113 +
config.h.win32.in | 6 +-
configure.in | 4 +-
demos/gtk-demo/Makefile.am | 3 +-
demos/gtk-demo/infobar.c | 104 +
demos/gtk-demo/printing.c | 61 +-
demos/gtk-demo/rotated_text.c | 6 +-
docs/reference/gdk/gdk-docs.sgml | 4 +
docs/reference/gdk/gdk-sections.txt | 7 +
docs/reference/gdk/tmpl/events.sgml | 1 +
docs/reference/gdk/tmpl/regions.sgml | 10 +
docs/reference/gdk/tmpl/windows.sgml | 101 +-
docs/reference/gtk/gtk-sections.txt | 6 +
docs/reference/gtk/tmpl/gtkmenu.sgml | 23 +
docs/reference/gtk/tmpl/gtkprintoperation.sgml | 46 +
docs/reference/gtk/tmpl/gtkprintsettings.sgml | 1 +
docs/reference/gtk/tmpl/gtkprintunixdialog.sgml | 60 +
docs/reference/gtk/tmpl/gtksettings.sgml | 2 +-
docs/reference/gtk/tmpl/gtkstatusicon.sgml | 23 +
docs/tutorial/gtk-tut.sgml | 10 +-
gdk-pixbuf/gdk-pixbuf-io.c | 4 +-
gdk-pixbuf/gdk-pixdata.c | 7 +-
gdk-pixbuf/makefile.msc | 3 +-
gdk/Makefile.am | 7 +-
gdk/directfb/gdkdisplay-directfb.c | 5 +-
gdk/directfb/gdkmain-directfb.c | 5 +-
gdk/directfb/gdkwindow-directfb.c | 5 +-
gdk/gdk.symbols | 49 +-
gdk/gdkcairo.c | 4 +
gdk/gdkdisplay.c | 642 +++-
gdk/gdkdisplay.h | 35 +
gdk/gdkdisplaymanager.c | 2 +-
gdk/gdkdraw.c | 128 +-
gdk/gdkdrawable.h | 24 +-
gdk/gdkevents.c | 76 +-
gdk/gdkevents.h | 3 +-
gdk/gdkgc.c | 262 +-
gdk/gdkinternals.h | 353 +-
gdk/gdkmarshalers.list | 4 +
gdk/gdkoffscreenwindow.c | 1281 +++++
gdk/gdkpango.c | 3 +-
gdk/gdkpixmap.c | 86 +-
gdk/gdkprivate.h | 3 +
gdk/gdkregion-generic.c | 52 +
gdk/gdkregion.h | 2 +
gdk/gdkscreen.h | 1 +
gdk/gdkwindow.c | 6954 +++++++++++++++++++----
gdk/gdkwindow.h | 48 +-
gdk/gdkwindowimpl.h | 100 +-
gdk/makefile.msc | 4 +-
gdk/quartz/GdkQuartzView.c | 61 +-
gdk/quartz/GdkQuartzView.h | 1 +
gdk/quartz/GdkQuartzWindow.c | 78 +-
gdk/quartz/gdkdisplay-quartz.c | 6 +
gdk/quartz/gdkdrawable-quartz.c | 171 +-
gdk/quartz/gdkevents-quartz.c | 1665 ++----
gdk/quartz/gdkgc-quartz.c | 11 +-
gdk/quartz/gdkgeometry-quartz.c | 68 +-
gdk/quartz/gdkinput.c | 4 +-
gdk/quartz/gdkinputprivate.h | 1 -
gdk/quartz/gdkpixmap-quartz.c | 30 +-
gdk/quartz/gdkprivate-quartz.h | 25 +-
gdk/quartz/gdkwindow-quartz.c | 1058 ++---
gdk/quartz/gdkwindow-quartz.h | 5 -
gdk/testgdk.c | 14 +-
gdk/win32/gdkdisplay-win32.c | 8 +-
gdk/win32/gdkdrawable-win32.c | 85 +-
gdk/win32/gdkdrawable-win32.h | 1 -
gdk/win32/gdkevents-win32.c | 812 +---
gdk/win32/gdkgc-win32.c | 13 +-
gdk/win32/gdkgeometry-win32.c | 677 +--
gdk/win32/gdkinput-win32.c | 109 +-
gdk/win32/gdkinput-win32.h | 1 -
gdk/win32/gdkmain-win32.c | 11 +-
gdk/win32/gdkpixmap-win32.c | 6 +-
gdk/win32/gdkprivate-win32.h | 10 +-
gdk/win32/gdkwindow-win32.c | 830 +--
gdk/win32/gdkwindow-win32.h | 17 +-
gdk/x11/gdkapplaunchcontext-x11.c | 8 +-
gdk/x11/gdkasync.c | 98 +
gdk/x11/gdkasync.h | 7 +
gdk/x11/gdkdevicemanager-core.c | 132 +-
gdk/x11/gdkdisplay-x11.c | 100 +-
gdk/x11/gdkdisplay-x11.h | 24 +-
gdk/x11/gdkdnd-x11.c | 4 +-
gdk/x11/gdkdrawable-x11.c | 161 +-
gdk/x11/gdkevents-x11.c | 140 +-
gdk/x11/gdkeventsource.c | 7 +-
gdk/x11/gdkgc-x11.c | 10 +-
gdk/x11/gdkgeometry-x11.c | 819 +---
gdk/x11/gdkinput-none.c | 19 +-
gdk/x11/gdkinput-x11.c | 257 +-
gdk/x11/gdkinput-xfree.c | 289 +-
gdk/x11/gdkinput.c | 231 +-
gdk/x11/gdkinputprivate.h | 43 +-
gdk/x11/gdkmain-x11.c | 331 +-
gdk/x11/gdkpixmap-x11.c | 30 +-
gdk/x11/gdkprivate-x11.h | 17 +-
gdk/x11/gdkproperty-x11.c | 13 +-
gdk/x11/gdkselection-x11.c | 7 +-
gdk/x11/gdkwindow-x11.c | 1715 ++----
gdk/x11/gdkwindow-x11.h | 39 +-
gtk/Makefile.am | 13 +-
gtk/gtk.symbols | 9 +
gtk/gtkactivatable.c | 4 +-
gtk/gtkbbox.c | 355 ++-
gtk/gtkbuilderparser.c | 36 +-
gtk/gtkbutton.c | 35 +-
gtk/gtkcalendar.c | 7 +-
gtk/gtkcellrendererpixbuf.c | 155 +-
gtk/gtkcellview.c | 38 +-
gtk/gtkcellview.h | 2 +
gtk/gtkcombobox.c | 29 +-
gtk/gtkdnd.c | 6 +-
gtk/gtkentrycompletion.c | 4 +-
gtk/gtkfilechooser.c | 11 +-
gtk/gtkfilechooserdefault.c | 30 +-
gtk/gtkfilechooserdialog.c | 1 -
gtk/gtkfilechooserprivate.h | 1 +
gtk/gtkfilechoosersettings.c | 2 +-
gtk/gtkfilechooserutils.c | 2 +-
gtk/gtkfontsel.c | 2 +-
gtk/gtkhandlebox.c | 3 +-
gtk/gtkhbbox.c | 212 +-
gtk/gtkhbbox.h | 3 +
gtk/gtkiconcache.c | 4 +-
gtk/gtkiconview.c | 25 +-
gtk/gtkinfobar.c | 142 +-
gtk/gtkliststore.c | 22 +-
gtk/gtkmenu.c | 101 +-
gtk/gtkmenu.h | 5 +
gtk/gtkmenuitem.c | 46 +
gtk/gtkmountoperation-stub.c | 68 +
gtk/gtkmountoperation-x11.c | 969 ++++
gtk/gtkmountoperation.c | 601 ++-
gtk/gtkmountoperationprivate.h | 53 +
gtk/gtknotebook.c | 19 +-
gtk/gtkprintoperation.c | 2 +-
gtk/gtkprintunixdialog.c | 1227 ++--
gtk/gtkrecentmanager.c | 7 +-
gtk/gtkrecentmanager.h | 2 +-
gtk/gtkscalebutton.c | 21 +-
gtk/gtksocket-x11.c | 10 +-
gtk/gtkstatusicon.c | 99 +-
gtk/gtkstatusicon.h | 3 +
gtk/gtkstock.c | 2 +-
gtk/gtktrayicon-x11.c | 16 +-
gtk/gtktreeprivate.h | 2 +
gtk/gtktreestore.c | 2 +-
gtk/gtktreeview.c | 66 +-
gtk/gtktreeviewcolumn.c | 31 +-
gtk/gtktreeviewcolumn.h | 2 +
gtk/gtkvbbox.c | 204 +-
gtk/gtkvbbox.h | 2 +
gtk/gtkwidget.c | 111 +-
gtk/gtkwidget.h | 4 +
gtk/makefile.msc.in | 18 +-
gtk/tests/builder.c | 10 +-
gtk/tests/testing.c | 12 +-
gtk/tests/treeview-scrolling.c | 2 +-
gtk/updateiconcache.c | 4 +-
modules/other/gail/gailtreeview.c | 10 +-
po-properties/af.po | 465 +-
po-properties/am.po | 460 +-
po-properties/ang.po | 458 +-
po-properties/ar.po | 463 +-
po-properties/as.po | 464 +-
po-properties/ast.po | 457 +-
po-properties/az.po | 464 +-
po-properties/az_IR.po | 457 +-
po-properties/be.po | 465 +-
po-properties/be latin po | 463 +-
po-properties/bg.po | 463 +-
po-properties/bn.po | 465 +-
po-properties/bn_IN.po | 465 +-
po-properties/br.po | 458 +-
po-properties/bs.po | 464 +-
po-properties/ca.po | 463 +-
po-properties/ca valencia po | 463 +-
po-properties/crh.po | 467 +-
po-properties/cs.po | 463 +-
po-properties/cy.po | 468 +-
po-properties/da.po | 3445 ++++++------
po-properties/de.po | 464 +-
po-properties/dz.po | 470 +-
po-properties/el.po | 463 +-
po-properties/en_CA.po | 463 +-
po-properties/en_GB.po | 463 +-
po-properties/eo.po | 457 +-
po-properties/es.po | 3433 ++++++------
po-properties/et.po | 463 +-
po-properties/eu.po | 464 +-
po-properties/fa.po | 461 +-
po-properties/fi.po | 463 +-
po-properties/fr.po | 463 +-
po-properties/ga.po | 460 +-
po-properties/gl.po | 463 +-
po-properties/gu.po | 463 +-
po-properties/he.po | 461 +-
po-properties/hi.po | 463 +-
po-properties/hr.po | 463 +-
po-properties/hu.po | 463 +-
po-properties/hy.po | 460 +-
po-properties/ia.po | 459 +-
po-properties/id.po | 467 +-
po-properties/io.po | 457 +-
po-properties/is.po | 462 +-
po-properties/it.po | 466 +-
po-properties/ja.po | 463 +-
po-properties/ka.po | 463 +-
po-properties/kn.po | 463 +-
po-properties/ko.po | 463 +-
po-properties/ku.po | 458 +-
po-properties/li.po | 465 +-
po-properties/lt.po | 463 +-
po-properties/lv.po | 463 +-
po-properties/mai.po | 463 +-
po-properties/mi.po | 459 +-
po-properties/mk.po | 463 +-
po-properties/ml.po | 463 +-
po-properties/mn.po | 468 +-
po-properties/mr.po | 463 +-
po-properties/ms.po | 464 +-
po-properties/nb.po | 463 +-
po-properties/ne.po | 463 +-
po-properties/nl.po | 464 +-
po-properties/nn.po | 464 +-
po-properties/nso.po | 465 +-
po-properties/oc.po | 460 +-
po-properties/or.po | 3672 ++++++------
po-properties/pa.po | 463 +-
po-properties/pl.po | 463 +-
po-properties/ps.po | 461 +-
po-properties/pt.po | 463 +-
po-properties/pt_BR.po | 465 +-
po-properties/ro.po | 463 +-
po-properties/ru.po | 463 +-
po-properties/rw.po | 463 +-
po-properties/si.po | 462 +-
po-properties/sk.po | 463 +-
po-properties/sl.po | 463 +-
po-properties/sq.po | 463 +-
po-properties/sr.po | 463 +-
po-properties/sr ije po | 463 +-
po-properties/sr latin po | 463 +-
po-properties/sv.po | 463 +-
po-properties/ta.po | 463 +-
po-properties/te.po | 463 +-
po-properties/th.po | 460 +-
po-properties/tk.po | 460 +-
po-properties/tr.po | 467 +-
po-properties/tt.po | 461 +-
po-properties/uk.po | 463 +-
po-properties/ur.po | 457 +-
po-properties/uz.po | 461 +-
po-properties/uz cyrillic po | 461 +-
po-properties/vi.po | 463 +-
po-properties/wa.po | 470 +-
po-properties/xh.po | 463 +-
po-properties/yi.po | 464 +-
po-properties/zh_CN.po | 463 +-
po-properties/zh_HK.po | 463 +-
po-properties/zh_TW.po | 463 +-
po/Makefile.in.in | 2 +
po/af.po | 334 +-
po/am.po | 332 +-
po/ang.po | 332 +-
po/ar.po | 336 +-
po/as.po | 336 +-
po/ast.po | 336 +-
po/az.po | 332 +-
po/az_IR.po | 331 +-
po/be.po | 332 +-
po/be latin po | 336 +-
po/bg.po | 336 +-
po/bn.po | 332 +-
po/bn_IN.po | 2202 ++++----
po/br.po | 332 +-
po/bs.po | 332 +-
po/ca.po | 336 +-
po/ca valencia po | 334 +-
po/crh.po | 337 +-
po/cs.po | 336 +-
po/cy.po | 334 +-
po/da.po | 336 +-
po/de.po | 387 +-
po/dz.po | 332 +-
po/el.po | 336 +-
po/en_CA.po | 334 +-
po/en_GB.po | 336 +-
po/eo.po | 332 +-
po/es.po | 312 +-
po/et.po | 137 +-
po/eu.po | 336 +-
po/fa.po | 332 +-
po/fi.po | 336 +-
po/fr.po | 336 +-
po/ga.po | 336 +-
po/gl.po | 336 +-
po/gu.po | 336 +-
po/he.po | 336 +-
po/hi.po | 2195 ++++----
po/hr.po | 334 +-
po/hu.po | 336 +-
po/hy.po | 332 +-
po/ia.po | 332 +-
po/id.po | 332 +-
po/io.po | 333 +-
po/is.po | 332 +-
po/it.po | 337 +-
po/ja.po | 336 +-
po/ka.po | 336 +-
po/kn.po | 336 +-
po/ko.po | 336 +-
po/ku.po | 334 +-
po/li.po | 332 +-
po/lt.po | 336 +-
po/lv.po | 336 +-
po/mai.po | 336 +-
po/mi.po | 332 +-
po/mk.po | 334 +-
po/ml.po | 336 +-
po/mn.po | 333 +-
po/mr.po | 336 +-
po/ms.po | 332 +-
po/nb.po | 2158 ++++----
po/ne.po | 332 +-
po/nl.po | 341 +-
po/nn.po | 337 +-
po/nso.po | 332 +-
po/oc.po | 333 +-
po/or.po | 336 +-
po/pa.po | 336 +-
po/pl.po | 336 +-
po/ps.po | 334 +-
po/pt.po | 336 +-
po/pt_BR.po | 2161 ++++----
po/ro.po | 336 +-
po/ru.po | 336 +-
po/rw.po | 335 +-
po/si.po | 334 +-
po/sk.po | 336 +-
po/sl.po | 336 +-
po/sq.po | 337 +-
po/sr.po | 336 +-
po/sr ije po | 332 +-
po/sr latin po | 336 +-
po/sv.po | 2831 +++++-----
po/ta.po | 336 +-
po/te.po | 336 +-
po/th.po | 336 +-
po/tk.po | 332 +-
po/tr.po | 337 +-
po/tt.po | 332 +-
po/uk.po | 336 +-
po/ur.po | 332 +-
po/uz.po | 334 +-
po/uz cyrillic po | 334 +-
po/vi.po | 428 +-
po/wa.po | 332 +-
po/xh.po | 332 +-
po/yi.po | 332 +-
po/zh_CN.po | 336 +-
po/zh_HK.po | 336 +-
po/zh_TW.po | 336 +-
tests/Makefile.am | 26 +
tests/flicker.c | 216 +
tests/gtkoffscreenbox.c | 653 +++
tests/gtkoffscreenbox.h | 52 +
tests/testbuttons.c | 145 +
tests/testclientmessage.c | 244 +-
tests/testgtk.c | 2 +-
tests/testoffscreen.c | 381 ++
tests/testorientable.c | 111 +
tests/testwindows.c | 1063 ++++
375 files changed, 72481 insertions(+), 55813 deletions(-)
---
diff --cc gdk/x11/gdkdevicemanager-core.c
index c56cec3,0000000..f4dce3f
mode 100644,000000..100644
--- a/gdk/x11/gdkdevicemanager-core.c
+++ b/gdk/x11/gdkdevicemanager-core.c
@@@ -1,933 -1,0 +1,959 @@@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 2009 Carlos Garnacho <carlosg gnome org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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 <gdk/gdktypes.h>
+#include <gdk/gdkdevicemanager.h>
+#include "gdkdevicemanager-core.h"
+#include "gdkeventtranslator.h"
+#include "gdkdevice-core.h"
+#include "gdkkeysyms.h"
++#include "gdkx.h"
+
+#ifdef HAVE_XKB
+#include <X11/XKBlib.h>
+#endif
+
+
+#define HAS_FOCUS(toplevel) \
+ ((toplevel)->has_focus || (toplevel)->has_pointer_focus)
+
+static GList * gdk_device_manager_core_get_devices (GdkDeviceManager *device_manager,
+ GdkDeviceType type);
+
+static void gdk_device_manager_event_translator_init (GdkEventTranslatorIface *iface);
+
- static gboolean gdk_device_manager_translate_event (GdkEventTranslator *translator,
- GdkDisplay *display,
- GdkEvent *event,
- XEvent *xevent);
++static gboolean gdk_device_manager_core_translate_event (GdkEventTranslator *translator,
++ GdkDisplay *display,
++ GdkEvent *event,
++ XEvent *xevent);
++static Window gdk_device_manager_core_get_event_window (GdkEventTranslator *translator,
++ XEvent *xevent);
+
+
+G_DEFINE_TYPE_WITH_CODE (GdkDeviceManagerCore, gdk_device_manager_core, GDK_TYPE_DEVICE_MANAGER,
+ G_IMPLEMENT_INTERFACE (GDK_TYPE_EVENT_TRANSLATOR,
+ gdk_device_manager_event_translator_init))
+
+static void
+gdk_device_manager_core_class_init (GdkDeviceManagerCoreClass *klass)
+{
+ GdkDeviceManagerClass *device_manager_class = GDK_DEVICE_MANAGER_CLASS (klass);
+
+ device_manager_class->get_devices = gdk_device_manager_core_get_devices;
+}
+
+static void
+gdk_device_manager_event_translator_init (GdkEventTranslatorIface *iface)
+{
- iface->translate_event = gdk_device_manager_translate_event;
++ iface->translate_event = gdk_device_manager_core_translate_event;
++ iface->get_event_window = gdk_device_manager_core_get_event_window;
+}
+
+static GdkDevice *
+create_core_pointer (GdkDisplay *display)
+{
+ /* FIXME: set mode */
+ return g_object_new (GDK_TYPE_DEVICE_CORE,
+ "name", "Core Pointer",
+ "input-source", GDK_SOURCE_MOUSE,
+ "has-cursor", TRUE,
+ "display", display,
+ NULL);
+}
+
+static void
+gdk_device_manager_core_init (GdkDeviceManagerCore *device_manager)
+{
+ GdkDisplay *display;
+
+ display = gdk_device_manager_get_display (GDK_DEVICE_MANAGER (device_manager));
+ device_manager->core_pointer = create_core_pointer (display);
+}
+
+static void
+translate_key_event (GdkDisplay *display,
+ GdkEvent *event,
+ XEvent *xevent)
+{
+ GdkKeymap *keymap = gdk_keymap_get_for_display (display);
+ gunichar c = 0;
+ gchar buf[7];
+
+ event->key.type = xevent->xany.type == KeyPress ? GDK_KEY_PRESS : GDK_KEY_RELEASE;
+ event->key.time = xevent->xkey.time;
+
+ event->key.state = (GdkModifierType) xevent->xkey.state;
+ event->key.group = _gdk_x11_get_group_for_state (display, xevent->xkey.state);
+ event->key.hardware_keycode = xevent->xkey.keycode;
+
+ event->key.keyval = GDK_VoidSymbol;
+
+ gdk_keymap_translate_keyboard_state (keymap,
+ event->key.hardware_keycode,
+ event->key.state,
+ event->key.group,
+ &event->key.keyval,
+ NULL, NULL, NULL);
+
+ _gdk_keymap_add_virtual_modifiers (keymap, &event->key.state);
+ event->key.is_modifier = _gdk_keymap_key_is_modifier (keymap, event->key.hardware_keycode);
+
+ /* Fill in event->string crudely, since various programs
+ * depend on it.
+ */
+ event->key.string = NULL;
+
+ if (event->key.keyval != GDK_VoidSymbol)
+ c = gdk_keyval_to_unicode (event->key.keyval);
+
+ if (c)
+ {
+ gsize bytes_written;
+ gint len;
+
+ /* Apply the control key - Taken from Xlib
+ */
+ if (event->key.state & GDK_CONTROL_MASK)
+ {
+ if ((c >= '@' && c < '\177') || c == ' ') c &= 0x1F;
+ else if (c == '2')
+ {
+ event->key.string = g_memdup ("\0\0", 2);
+ event->key.length = 1;
+ buf[0] = '\0';
+ goto out;
+ }
+ else if (c >= '3' && c <= '7') c -= ('3' - '\033');
+ else if (c == '8') c = '\177';
+ else if (c == '/') c = '_' & 0x1F;
+ }
+
+ len = g_unichar_to_utf8 (c, buf);
+ buf[len] = '\0';
+
+ event->key.string = g_locale_from_utf8 (buf, len,
+ NULL, &bytes_written,
+ NULL);
+ if (event->key.string)
+ event->key.length = bytes_written;
+ }
+ else if (event->key.keyval == GDK_Escape)
+ {
+ event->key.length = 1;
+ event->key.string = g_strdup ("\033");
+ }
+ else if (event->key.keyval == GDK_Return ||
+ event->key.keyval == GDK_KP_Enter)
+ {
+ event->key.length = 1;
+ event->key.string = g_strdup ("\r");
+ }
+
+ if (!event->key.string)
+ {
+ event->key.length = 0;
+ event->key.string = g_strdup ("");
+ }
+
+ out:
+#ifdef G_ENABLE_DEBUG
+ if (_gdk_debug_flags & GDK_DEBUG_EVENTS)
+ {
+ g_message ("%s:\t\twindow: %ld key: %12s %d",
+ event->type == GDK_KEY_PRESS ? "key press " : "key release",
+ xevent->xkey.window,
+ event->key.keyval ? gdk_keyval_name (event->key.keyval) : "(none)",
+ event->key.keyval);
+
+ if (event->key.length > 0)
+ g_message ("\t\tlength: %4d string: \"%s\"",
+ event->key.length, buf);
+ }
+#endif /* G_ENABLE_DEBUG */
+ return;
+}
+
+#ifdef G_ENABLE_DEBUG
+static const char notify_modes[][19] = {
+ "NotifyNormal",
+ "NotifyGrab",
+ "NotifyUngrab",
+ "NotifyWhileGrabbed"
+};
+
+static const char notify_details[][23] = {
+ "NotifyAncestor",
+ "NotifyVirtual",
+ "NotifyInferior",
+ "NotifyNonlinear",
+ "NotifyNonlinearVirtual",
+ "NotifyPointer",
+ "NotifyPointerRoot",
+ "NotifyDetailNone"
+};
+#endif
+
+static void
+set_user_time (GdkWindow *window,
+ GdkEvent *event)
+{
+ g_return_if_fail (event != NULL);
+
+ window = gdk_window_get_toplevel (event->client.window);
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ /* If an event doesn't have a valid timestamp, we shouldn't use it
+ * to update the latest user interaction time.
+ */
+ if (gdk_event_get_time (event) != GDK_CURRENT_TIME)
+ gdk_x11_window_set_user_time (gdk_window_get_toplevel (window),
+ gdk_event_get_time (event));
+}
+
+static void
+generate_focus_event (GdkWindow *window,
+ gboolean in)
+{
+ GdkEvent event;
+
+ event.type = GDK_FOCUS_CHANGE;
+ event.focus_change.window = window;
+ event.focus_change.send_event = FALSE;
+ event.focus_change.in = in;
+
+ gdk_event_put (&event);
+}
+
+static gboolean
+set_screen_from_root (GdkDisplay *display,
+ GdkEvent *event,
+ Window xrootwin)
+{
+ GdkScreen *screen;
+
+ screen = _gdk_x11_display_screen_for_xrootwin (display, xrootwin);
+
+ if (screen)
+ {
+ gdk_event_set_screen (event, screen);
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static GdkCrossingMode
+translate_crossing_mode (int mode)
+{
+ switch (mode)
+ {
+ case NotifyNormal:
+ return GDK_CROSSING_NORMAL;
+ case NotifyGrab:
+ return GDK_CROSSING_GRAB;
+ case NotifyUngrab:
+ return GDK_CROSSING_UNGRAB;
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+static GdkNotifyType
+translate_notify_type (int detail)
+{
+ switch (detail)
+ {
+ case NotifyInferior:
+ return GDK_NOTIFY_INFERIOR;
+ case NotifyAncestor:
+ return GDK_NOTIFY_ANCESTOR;
+ case NotifyVirtual:
+ return GDK_NOTIFY_VIRTUAL;
+ case NotifyNonlinear:
+ return GDK_NOTIFY_NONLINEAR;
+ case NotifyNonlinearVirtual:
+ return GDK_NOTIFY_NONLINEAR_VIRTUAL;
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+static gboolean
- gdk_device_manager_translate_event (GdkEventTranslator *translator,
- GdkDisplay *display,
- GdkEvent *event,
- XEvent *xevent)
++gdk_device_manager_core_translate_event (GdkEventTranslator *translator,
++ GdkDisplay *display,
++ GdkEvent *event,
++ XEvent *xevent)
+{
+ GdkDeviceManagerCore *device_manager;
+ GdkWindow *window, *filter_window;
+ GdkWindowObject *window_private;
+ GdkWindowImplX11 *window_impl = NULL;
+ gboolean return_val;
- gint xoffset = 0, yoffset = 0;
+ GdkToplevelX11 *toplevel = NULL;
+ GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
+
+ device_manager = GDK_DEVICE_MANAGER_CORE (translator);
+ return_val = FALSE;
+
+ /* init these, since the done: block uses them */
+ window = NULL;
+ window_private = NULL;
+ event->any.window = NULL;
+
+ /* Run default filters */
+#if 0
+ if (_gdk_default_filters)
+ {
+ /* Apply global filters */
+ GdkFilterReturn result;
+ result = gdk_event_apply_filters (xevent, event,
+ _gdk_default_filters);
+
+ if (result != GDK_FILTER_CONTINUE)
+ {
+ return_val = (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE;
+ goto done;
+ }
+ }
+#endif
+
+ /* Find the GdkWindow that this event relates to.
+ * Basically this means substructure events
+ * are reported same as structure events
+ */
+ window = gdk_event_translator_get_event_window (translator, display, xevent);
+ filter_window = gdk_event_translator_get_filter_window (translator, display, xevent);
+ window_private = (GdkWindowObject *) window;
+
+ if (window)
+ {
+ toplevel = _gdk_x11_window_get_toplevel (window);
+ window_impl = GDK_WINDOW_IMPL_X11 (window_private->impl);
+
+ /* Move key events on focus window to the real toplevel, and
+ * filter out all other events on focus window
+ */
+ /* FIXME: is this needed? */
+#if 0
+ if (toplevel && xwindow == toplevel->focus_window)
+ {
+ switch (xevent->type)
+ {
+ case KeyPress:
+ case KeyRelease:
+ xwindow = GDK_WINDOW_XID (window);
+ xevent->xany.window = xwindow;
+ break;
+ default:
+ return FALSE;
+ }
+ }
+#endif
+
+ g_object_ref (window);
+ }
+
+ event->any.window = window;
+ event->any.send_event = xevent->xany.send_event ? TRUE : FALSE;
+
+ if (window_private && GDK_WINDOW_DESTROYED (window))
+ {
+ if (xevent->type != DestroyNotify)
+ {
+ return_val = FALSE;
+ goto done;
+ }
+ }
+#if 0
+ else if (filter_window)
+ {
+ /* Apply per-window filters */
+ GdkWindowObject *filter_private = (GdkWindowObject *) filter_window;
+ GdkFilterReturn result;
+
+ if (filter_private->filters)
+ {
+ g_object_ref (filter_window);
+
+ result = gdk_event_apply_filters (xevent, event,
+ filter_private->filters);
+
+ g_object_unref (filter_window);
+
+ if (result != GDK_FILTER_CONTINUE)
+ {
+ return_val = (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE;
+ goto done;
+ }
+ }
+ }
+#endif
+
+ if (window &&
+ (xevent->type == MotionNotify ||
+ xevent->type == ButtonRelease))
+ {
+ if (_gdk_moveresize_handle_event (xevent))
+ {
+ return_val = FALSE;
+ goto done;
+ }
+ }
+
+ /* 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;
+
- if (window)
- _gdk_x11_window_get_offsets (window, &xoffset, &yoffset);
-
+ switch (xevent->type)
+ {
+ case KeyPress:
+ if (window_private == NULL)
+ {
+ return_val = FALSE;
+ break;
+ }
+ translate_key_event (display, event, xevent);
+ set_user_time (window, event);
+ break;
+
+ case KeyRelease:
+ if (window_private == NULL)
+ {
+ return_val = FALSE;
+ break;
+ }
+
+ /* Emulate detectable auto-repeat by checking to see
+ * if the next event is a key press with the same
+ * keycode and timestamp, and if so, ignoring the event.
+ */
+
+ if (!display_x11->have_xkb_autorepeat && XPending (xevent->xkey.display))
+ {
+ XEvent next_event;
+
+ XPeekEvent (xevent->xkey.display, &next_event);
+
+ if (next_event.type == KeyPress &&
+ next_event.xkey.keycode == xevent->xkey.keycode &&
+ next_event.xkey.time == xevent->xkey.time)
+ {
+ return_val = FALSE;
+ break;
+ }
+ }
+
+ translate_key_event (display, event, xevent);
+ break;
+
+ case ButtonPress:
+ GDK_NOTE (EVENTS,
+ g_message ("button press:\t\twindow: %ld x,y: %d %d button: %d",
+ xevent->xbutton.window,
+ xevent->xbutton.x, xevent->xbutton.y,
+ xevent->xbutton.button));
+
- if (window_private == NULL ||
- ((window_private->extension_events != 0) &&
- display_x11->input_ignore_core))
++ if (window_private == NULL)
+ {
+ return_val = FALSE;
+ break;
+ }
+
+ /* If we get a ButtonPress event where the button is 4 or 5,
+ it's a Scroll event */
+ switch (xevent->xbutton.button)
+ {
+ case 4: /* up */
+ case 5: /* down */
+ case 6: /* left */
+ case 7: /* right */
+ event->scroll.type = GDK_SCROLL;
+
+ if (xevent->xbutton.button == 4)
+ event->scroll.direction = GDK_SCROLL_UP;
+ else if (xevent->xbutton.button == 5)
+ event->scroll.direction = GDK_SCROLL_DOWN;
+ else if (xevent->xbutton.button == 6)
+ event->scroll.direction = GDK_SCROLL_LEFT;
+ else
+ event->scroll.direction = GDK_SCROLL_RIGHT;
+
+ event->scroll.window = window;
+ event->scroll.time = xevent->xbutton.time;
- event->scroll.x = xevent->xbutton.x + xoffset;
- event->scroll.y = xevent->xbutton.y + yoffset;
++ event->scroll.x = xevent->xbutton.x;
++ event->scroll.y = xevent->xbutton.y;
+ event->scroll.x_root = (gfloat) xevent->xbutton.x_root;
+ event->scroll.y_root = (gfloat) xevent->xbutton.y_root;
+ event->scroll.state = (GdkModifierType) xevent->xbutton.state;
+ event->scroll.device = device_manager->core_pointer;
+
+ if (!set_screen_from_root (display, event, xevent->xbutton.root))
+ {
+ return_val = FALSE;
+ break;
+ }
+
+ break;
+
+ default:
+ event->button.type = GDK_BUTTON_PRESS;
+ event->button.window = window;
+ event->button.time = xevent->xbutton.time;
- event->button.x = xevent->xbutton.x + xoffset;
- event->button.y = xevent->xbutton.y + yoffset;
++ 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.axes = NULL;
+ event->button.state = (GdkModifierType) xevent->xbutton.state;
+ event->button.button = xevent->xbutton.button;
+ event->button.device = device_manager->core_pointer;
+
+ if (!set_screen_from_root (display, event, xevent->xbutton.root))
- {
- return_val = FALSE;
- break;
- }
++ return_val = FALSE;
+
- _gdk_event_button_generate (display, event);
+ break;
+ }
+
+ set_user_time (window, event);
+
- _gdk_xgrab_check_button_event (window, xevent);
+ break;
+
+ case ButtonRelease:
+ GDK_NOTE (EVENTS,
+ g_message ("button release:\twindow: %ld x,y: %d %d button: %d",
+ xevent->xbutton.window,
+ xevent->xbutton.x, xevent->xbutton.y,
+ xevent->xbutton.button));
+
- if (window_private == NULL ||
- ((window_private->extension_events != 0) &&
- display_x11->input_ignore_core))
++ if (window_private == NULL)
+ {
+ return_val = FALSE;
+ break;
+ }
+
+ /* We treat button presses as scroll wheel events, so ignore the release */
+ if (xevent->xbutton.button == 4 || xevent->xbutton.button == 5 ||
+ xevent->xbutton.button == 6 || xevent->xbutton.button == 7)
+ {
+ 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 + xoffset;
- event->button.y = xevent->xbutton.y + yoffset;
++ 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.axes = NULL;
+ event->button.state = (GdkModifierType) xevent->xbutton.state;
+ event->button.button = xevent->xbutton.button;
+ event->button.device = device_manager->core_pointer;
+
+ if (!set_screen_from_root (display, event, xevent->xbutton.root))
- {
- return_val = FALSE;
- break;
- }
++ return_val = FALSE;
+
- _gdk_xgrab_check_button_event (window, xevent);
+ break;
+
+ case MotionNotify:
+ GDK_NOTE (EVENTS,
+ g_message ("motion notify:\t\twindow: %ld x,y: %d %d hint: %s",
+ xevent->xmotion.window,
+ xevent->xmotion.x, xevent->xmotion.y,
+ (xevent->xmotion.is_hint) ? "true" : "false"));
+
- if (window_private == NULL ||
- ((window_private->extension_events != 0) &&
- display_x11->input_ignore_core))
++ if (window_private == NULL)
+ {
+ 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 + xoffset;
- event->motion.y = xevent->xmotion.y + yoffset;
++ 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.axes = NULL;
+ event->motion.state = (GdkModifierType) xevent->xmotion.state;
+ event->motion.is_hint = xevent->xmotion.is_hint;
+ event->motion.device = device_manager->core_pointer;
+
+ if (!set_screen_from_root (display, event, xevent->xbutton.root))
+ {
+ return_val = FALSE;
+ break;
+ }
+
+ break;
+
+ case EnterNotify:
+ GDK_NOTE (EVENTS,
+ g_message ("enter notify:\t\twindow: %ld detail: %d subwin: %ld",
+ xevent->xcrossing.window,
+ xevent->xcrossing.detail,
+ xevent->xcrossing.subwindow));
+
+ if (window_private == NULL)
+ {
+ return_val = FALSE;
+ break;
+ }
+
+ if (!set_screen_from_root (display, event, xevent->xbutton.root))
+ {
+ return_val = FALSE;
+ break;
+ }
+
+ /* Handle focusing (in the case where no window manager is running */
+ if (toplevel && xevent->xcrossing.detail != NotifyInferior)
+ {
+ toplevel->has_pointer = TRUE;
+
+ if (xevent->xcrossing.focus && !toplevel->has_focus_window)
+ {
+ gboolean had_focus = HAS_FOCUS (toplevel);
+
+ toplevel->has_pointer_focus = TRUE;
+
+ if (HAS_FOCUS (toplevel) != had_focus)
+ generate_focus_event (window, TRUE);
+ }
+ }
+
- #if 0
- /* Tell XInput stuff about it if appropriate */
- if (window_private &&
- !GDK_WINDOW_DESTROYED (window) &&
- window_private->extension_events != 0)
- _gdk_input_enter_event (&xevent->xcrossing, window);
- #endif
-
+ 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_for_display (display, xevent->xcrossing.subwindow);
+ else
+ event->crossing.subwindow = NULL;
+
+ event->crossing.time = xevent->xcrossing.time;
- event->crossing.x = xevent->xcrossing.x + xoffset;
- event->crossing.y = xevent->xcrossing.y + yoffset;
++ 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;
+
+ event->crossing.mode = translate_crossing_mode (xevent->xcrossing.mode);
+ event->crossing.detail = translate_notify_type (xevent->xcrossing.detail);
+
+ event->crossing.focus = xevent->xcrossing.focus;
+ event->crossing.state = xevent->xcrossing.state;
+
+ break;
+
+ case LeaveNotify:
+ GDK_NOTE (EVENTS,
+ g_message ("leave notify:\t\twindow: %ld detail: %d subwin: %ld",
+ xevent->xcrossing.window,
+ xevent->xcrossing.detail, xevent->xcrossing.subwindow));
+
+ if (window_private == NULL)
+ {
+ return_val = FALSE;
+ break;
+ }
+
+ if (!set_screen_from_root (display, event, xevent->xbutton.root))
+ {
+ return_val = FALSE;
+ break;
+ }
+
+ /* Handle focusing (in the case where no window manager is running */
+ if (toplevel && xevent->xcrossing.detail != NotifyInferior)
+ {
+ toplevel->has_pointer = FALSE;
+
+ if (xevent->xcrossing.focus && !toplevel->has_focus_window)
+ {
+ gboolean had_focus = HAS_FOCUS (toplevel);
+
+ toplevel->has_pointer_focus = FALSE;
+
+ if (HAS_FOCUS (toplevel) != had_focus)
+ generate_focus_event (window, FALSE);
+ }
+ }
+
+ 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_for_display (display, xevent->xcrossing.subwindow);
+ else
+ event->crossing.subwindow = NULL;
+
+ event->crossing.time = xevent->xcrossing.time;
- event->crossing.x = xevent->xcrossing.x + xoffset;
- event->crossing.y = xevent->xcrossing.y + yoffset;
++ 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;
+
+ event->crossing.mode = translate_crossing_mode (xevent->xcrossing.mode);
+ event->crossing.detail = translate_notify_type (xevent->xcrossing.detail);
+
+ event->crossing.focus = xevent->xcrossing.focus;
+ event->crossing.state = xevent->xcrossing.state;
+
+ break;
+
+ /* We only care about focus events that indicate that _this_
+ * window (not a ancestor or child) got or lost the focus
+ */
+ case FocusIn:
+ GDK_NOTE (EVENTS,
+ g_message ("focus in:\t\twindow: %ld, detail: %s, mode: %s",
+ xevent->xfocus.window,
+ notify_details[xevent->xfocus.detail],
+ notify_modes[xevent->xfocus.mode]));
+
+ if (toplevel)
+ {
+ gboolean had_focus = HAS_FOCUS (toplevel);
+
+ switch (xevent->xfocus.detail)
+ {
+ case NotifyAncestor:
+ case NotifyVirtual:
+ /* When the focus moves from an ancestor of the window to
+ * the window or a descendent of the window, *and* the
+ * pointer is inside the window, then we were previously
+ * receiving keystroke events in the has_pointer_focus
+ * case and are now receiving them in the
+ * has_focus_window case.
+ */
+ if (toplevel->has_pointer &&
+ xevent->xfocus.mode != NotifyGrab &&
+ xevent->xfocus.mode != NotifyUngrab)
+ toplevel->has_pointer_focus = FALSE;
+
+ /* fall through */
+ case NotifyNonlinear:
+ case NotifyNonlinearVirtual:
+ if (xevent->xfocus.mode != NotifyGrab &&
+ xevent->xfocus.mode != NotifyUngrab)
+ toplevel->has_focus_window = TRUE;
+ /* We pretend that the focus moves to the grab
+ * window, so we pay attention to NotifyGrab
+ * NotifyUngrab, and ignore NotifyWhileGrabbed
+ */
+ if (xevent->xfocus.mode != NotifyWhileGrabbed)
+ toplevel->has_focus = TRUE;
+ break;
+ case NotifyPointer:
+ /* The X server sends NotifyPointer/NotifyGrab,
+ * but the pointer focus is ignored while a
+ * grab is in effect
+ */
+ if (xevent->xfocus.mode != NotifyGrab &&
+ xevent->xfocus.mode != NotifyUngrab)
+ toplevel->has_pointer_focus = TRUE;
+ break;
+ case NotifyInferior:
+ case NotifyPointerRoot:
+ case NotifyDetailNone:
+ break;
+ }
+
+ if (HAS_FOCUS (toplevel) != had_focus)
+ generate_focus_event (window, TRUE);
+ }
+ break;
+ case FocusOut:
+ GDK_NOTE (EVENTS,
+ g_message ("focus out:\t\twindow: %ld, detail: %s, mode: %s",
+ xevent->xfocus.window,
+ notify_details[xevent->xfocus.detail],
+ notify_modes[xevent->xfocus.mode]));
+
+ if (toplevel)
+ {
+ gboolean had_focus = HAS_FOCUS (toplevel);
+
+ switch (xevent->xfocus.detail)
+ {
+ case NotifyAncestor:
+ case NotifyVirtual:
+ /* When the focus moves from the window or a descendent
+ * of the window to an ancestor of the window, *and* the
+ * pointer is inside the window, then we were previously
+ * receiving keystroke events in the has_focus_window
+ * case and are now receiving them in the
+ * has_pointer_focus case.
+ */
+ if (toplevel->has_pointer &&
+ xevent->xfocus.mode != NotifyGrab &&
+ xevent->xfocus.mode != NotifyUngrab)
+ toplevel->has_pointer_focus = TRUE;
+
+ /* fall through */
+ case NotifyNonlinear:
+ case NotifyNonlinearVirtual:
+ if (xevent->xfocus.mode != NotifyGrab &&
+ xevent->xfocus.mode != NotifyUngrab)
+ toplevel->has_focus_window = FALSE;
+ if (xevent->xfocus.mode != NotifyWhileGrabbed)
+ toplevel->has_focus = FALSE;
+ break;
+ case NotifyPointer:
+ if (xevent->xfocus.mode != NotifyGrab &&
+ xevent->xfocus.mode != NotifyUngrab)
+ toplevel->has_pointer_focus = FALSE;
+ break;
+ case NotifyInferior:
+ case NotifyPointerRoot:
+ case NotifyDetailNone:
+ break;
+ }
+
+ if (HAS_FOCUS (toplevel) != had_focus)
+ generate_focus_event (window, FALSE);
+ }
+ break;
+
+ default:
+#ifdef HAVE_XKB
+ if (xevent->type == display_x11->xkb_event_type)
+ {
+ XkbEvent *xkb_event = (XkbEvent *)xevent;
+
+ switch (xkb_event->any.xkb_type)
+ {
+ case XkbNewKeyboardNotify:
+ case XkbMapNotify:
+ _gdk_keymap_keys_changed (display);
+
+ return_val = FALSE;
+ break;
+
+ case XkbStateNotify:
+ _gdk_keymap_state_changed (display, xevent);
+ break;
+ }
+ }
+ else
+#endif
+ return_val = FALSE;
+ }
+
+ done:
+ if (return_val)
+ {
+ if (event->any.window)
+ g_object_ref (event->any.window);
+
+ if (((event->any.type == GDK_ENTER_NOTIFY) ||
+ (event->any.type == GDK_LEAVE_NOTIFY)) &&
+ (event->crossing.subwindow != NULL))
+ g_object_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)
+ g_object_unref (window);
+
+ return return_val;
+}
+
++static gboolean
++is_parent_of (GdkWindow *parent,
++ GdkWindow *child)
++{
++ GdkWindow *w;
++
++ w = child;
++ while (w != NULL)
++ {
++ if (w == parent)
++ return TRUE;
++
++ w = gdk_window_get_parent (w);
++ }
++
++ return FALSE;
++}
++
++static Window
++gdk_device_manager_core_get_event_window (GdkEventTranslator *translator,
++ XEvent *xevent)
++{
++ GdkDisplay *display;
++
++ display = gdk_device_manager_get_display (GDK_DEVICE_MANAGER (translator));
++
++ /* Apply keyboard grabs to non-native windows */
++ if (/* Is key event */
++ (xevent->type == KeyPress || xevent->type == KeyRelease) &&
++ /* And we have a grab */
++ display->keyboard_grab.window != NULL)
++ {
++ GdkWindow *window;
++
++ window = gdk_window_lookup_for_display (display, xevent->xkey.window);
++
++ if (/* The window is not a descendant of the grabbed window */
++ !is_parent_of ((GdkWindow *)display->keyboard_grab.window, window) ||
++ /* Or owner event is false */
++ !display->keyboard_grab.owner_events)
++ {
++ /* Report key event against grab window */
++ return GDK_WINDOW_XID (display->keyboard_grab.window);
++ }
++ }
++
++ return None;
++}
++
+static GList *
+gdk_device_manager_core_get_devices (GdkDeviceManager *device_manager,
+ GdkDeviceType type)
+{
+ GdkDeviceManagerCore *device_manager_core;
+ GList *devices = NULL;
+
+ if (type == GDK_DEVICE_TYPE_MASTER)
+ {
+ device_manager_core = (GdkDeviceManagerCore *) device_manager;
+ devices = g_list_prepend (devices, device_manager_core->core_pointer);
+ }
+
+ return devices;
+}
diff --cc gdk/x11/gdkdisplay-x11.c
index c2260fd,a7b5847..a106222
--- a/gdk/x11/gdkdisplay-x11.c
+++ b/gdk/x11/gdkdisplay-x11.c
@@@ -31,10 -31,9 +31,11 @@@
#include <glib.h>
#include "gdkx.h"
+ #include "gdkasync.h"
#include "gdkdisplay.h"
#include "gdkdisplay-x11.h"
+#include "gdkeventsource.h"
+#include "gdkeventtranslator.h"
#include "gdkscreen.h"
#include "gdkscreen-x11.h"
#include "gdkinternals.h"
@@@ -146,878 -136,6 +147,876 @@@ _gdk_display_x11_init (GdkDisplayX11 *d
{
}
+static void
+gdk_display_x11_event_translator_init (GdkEventTranslatorIface *iface)
+{
+ iface->translate_event = gdk_display_x11_translate_event;
+}
+
+static void
+do_net_wm_state_changes (GdkWindow *window)
+{
+ GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (window);
+ GdkWindowState old_state;
+
+ if (GDK_WINDOW_DESTROYED (window) ||
+ gdk_window_get_window_type (window) != GDK_WINDOW_TOPLEVEL)
+ return;
+
+ old_state = gdk_window_get_state (window);
+
+ /* For found_sticky to remain TRUE, we have to also be on desktop
+ * 0xFFFFFFFF
+ */
+ if (old_state & GDK_WINDOW_STATE_STICKY)
+ {
+ if (!(toplevel->have_sticky && toplevel->on_all_desktops))
+ gdk_synthesize_window_state (window,
+ GDK_WINDOW_STATE_STICKY,
+ 0);
+ }
+ else
+ {
+ if (toplevel->have_sticky || toplevel->on_all_desktops)
+ gdk_synthesize_window_state (window,
+ 0,
+ GDK_WINDOW_STATE_STICKY);
+ }
+
+ if (old_state & GDK_WINDOW_STATE_FULLSCREEN)
+ {
+ if (!toplevel->have_fullscreen)
+ gdk_synthesize_window_state (window,
+ GDK_WINDOW_STATE_FULLSCREEN,
+ 0);
+ }
+ else
+ {
+ if (toplevel->have_fullscreen)
+ gdk_synthesize_window_state (window,
+ 0,
+ GDK_WINDOW_STATE_FULLSCREEN);
+ }
+
+ /* Our "maximized" means both vertical and horizontal; if only one,
+ * we don't expose that via GDK
+ */
+ if (old_state & GDK_WINDOW_STATE_MAXIMIZED)
+ {
+ if (!(toplevel->have_maxvert && toplevel->have_maxhorz))
+ gdk_synthesize_window_state (window,
+ GDK_WINDOW_STATE_MAXIMIZED,
+ 0);
+ }
+ else
+ {
+ if (toplevel->have_maxvert && toplevel->have_maxhorz)
+ gdk_synthesize_window_state (window,
+ 0,
+ GDK_WINDOW_STATE_MAXIMIZED);
+ }
+}
+
+static void
+gdk_check_wm_desktop_changed (GdkWindow *window)
+{
+ GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (window);
+ GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
+
+ Atom type;
+ gint format;
+ gulong nitems;
+ gulong bytes_after;
+ guchar *data;
+ gulong *desktop;
+
+ type = None;
+ gdk_error_trap_push ();
+ XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display),
+ GDK_WINDOW_XID (window),
+ gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_DESKTOP"),
+ 0, G_MAXLONG, False, XA_CARDINAL, &type,
+ &format, &nitems,
+ &bytes_after, &data);
+ gdk_error_trap_pop ();
+
+ if (type != None)
+ {
+ desktop = (gulong *)data;
+ toplevel->on_all_desktops = (*desktop == 0xFFFFFFFF);
+ XFree (desktop);
+ }
+ else
+ toplevel->on_all_desktops = FALSE;
+
+ do_net_wm_state_changes (window);
+}
+
+static void
+gdk_check_wm_state_changed (GdkWindow *window)
+{
+ GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (window);
+ GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
+
+ Atom type;
+ gint format;
+ gulong nitems;
+ gulong bytes_after;
+ guchar *data;
+ Atom *atoms = NULL;
+ gulong i;
+
+ gboolean had_sticky = toplevel->have_sticky;
+
+ toplevel->have_sticky = FALSE;
+ toplevel->have_maxvert = FALSE;
+ toplevel->have_maxhorz = FALSE;
+ toplevel->have_fullscreen = FALSE;
+
+ type = None;
+ gdk_error_trap_push ();
+ XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
+ gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE"),
+ 0, G_MAXLONG, False, XA_ATOM, &type, &format, &nitems,
+ &bytes_after, &data);
+ gdk_error_trap_pop ();
+
+ if (type != None)
+ {
+ Atom sticky_atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_STICKY");
+ Atom maxvert_atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_MAXIMIZED_VERT");
+ Atom maxhorz_atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_MAXIMIZED_HORZ");
+ Atom fullscreen_atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_FULLSCREEN");
+
+ atoms = (Atom *)data;
+
+ i = 0;
+ while (i < nitems)
+ {
+ if (atoms[i] == sticky_atom)
+ toplevel->have_sticky = TRUE;
+ else if (atoms[i] == maxvert_atom)
+ toplevel->have_maxvert = TRUE;
+ else if (atoms[i] == maxhorz_atom)
+ toplevel->have_maxhorz = TRUE;
+ else if (atoms[i] == fullscreen_atom)
+ toplevel->have_fullscreen = TRUE;
+
+ ++i;
+ }
+
+ XFree (atoms);
+ }
+
+ /* When have_sticky is turned on, we have to check the DESKTOP property
+ * as well.
+ */
+ if (toplevel->have_sticky && !had_sticky)
+ gdk_check_wm_desktop_changed (window);
+ else
+ do_net_wm_state_changes (window);
+}
+
+static gboolean
+gdk_display_x11_translate_event (GdkEventTranslator *translator,
+ GdkDisplay *display,
+ GdkEvent *event,
+ XEvent *xevent)
+{
+ GdkWindow *window, *filter_window;
+ GdkWindowObject *window_private;
+ GdkWindowImplX11 *window_impl = NULL;
+ GdkScreen *screen = NULL;
+ GdkScreenX11 *screen_x11 = NULL;
+ GdkToplevelX11 *toplevel = NULL;
+ GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
- gint xoffset = 0, yoffset = 0;
+ gboolean return_val;
+ Window xwindow = None;
+
+ /* FIXME: default filters */
+
+ /* Find the GdkWindow that this event relates to.
+ * Basically this means substructure events
+ * are reported same as structure events
+ */
+ window = gdk_event_translator_get_event_window (translator, display, xevent);
+ filter_window = gdk_event_translator_get_filter_window (translator, display, xevent);
+ window_private = (GdkWindowObject *) window;
+
+ if (window)
+ {
+ screen = GDK_WINDOW_SCREEN (window);
+ screen_x11 = GDK_SCREEN_X11 (screen);
+ toplevel = _gdk_x11_window_get_toplevel (window);
+ window_impl = GDK_WINDOW_IMPL_X11 (window_private->impl);
+ xwindow = GDK_WINDOW_XID (window);
+
+ g_object_ref (window);
+ }
+
+ event->any.window = window;
+ event->any.send_event = xevent->xany.send_event ? TRUE : FALSE;
+
+ if (window_private && GDK_WINDOW_DESTROYED (window))
+ {
+ if (xevent->type != DestroyNotify)
+ {
+ return_val = FALSE;
+ goto done;
+ }
+ }
+#if 0
+ else if (filter_window)
+ {
+ /* Apply per-window filters */
+ GdkWindowObject *filter_private = (GdkWindowObject *) filter_window;
+ GdkFilterReturn result;
+
+ if (filter_private->filters)
+ {
+ g_object_ref (filter_window);
+
+ result = gdk_event_apply_filters (xevent, event,
+ filter_private->filters);
+
+ g_object_unref (filter_window);
+
+ if (result != GDK_FILTER_CONTINUE)
+ {
+ return_val = (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE;
+ goto done;
+ }
+ }
+ }
+#endif
+
+ /* FIXME: if window is NULL, xwindow should still have something meaningful here? */
+ if (xwindow != None &&
+ screen_x11 && screen_x11->wmspec_check_window != None &&
+ xwindow == screen_x11->wmspec_check_window)
+ {
+ if (xevent->type == DestroyNotify)
+ {
+ screen_x11->wmspec_check_window = None;
+ g_free (screen_x11->window_manager_name);
+ screen_x11->window_manager_name = g_strdup ("unknown");
+
+ /* careful, reentrancy */
+ _gdk_x11_screen_window_manager_changed (GDK_SCREEN (screen_x11));
+ }
+
+ /* Eat events on this window unless someone had wrapped
+ * it as a foreign window
+ */
+ if (window == NULL)
+ {
+ return_val = FALSE;
+ goto done;
+ }
+ }
+
+ /* 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;
+
- if (window)
- _gdk_x11_window_get_offsets (window, &xoffset, &yoffset);
-
+ switch (xevent->type)
+ {
+ case KeymapNotify:
+ GDK_NOTE (EVENTS,
+ g_message ("keymap notify"));
+
+ /* Not currently handled */
+ return_val = FALSE;
+ break;
+
+ case Expose:
+ GDK_NOTE (EVENTS,
+ g_message ("expose:\t\twindow: %ld %d x,y: %d %d w,h: %d %d%s",
+ xevent->xexpose.window, xevent->xexpose.count,
+ xevent->xexpose.x, xevent->xexpose.y,
+ xevent->xexpose.width, xevent->xexpose.height,
+ event->any.send_event ? " (send)" : ""));
+
+ if (window_private == NULL)
+ {
+ return_val = FALSE;
+ break;
+ }
+
+ {
+ GdkRectangle expose_rect;
+
- expose_rect.x = xevent->xexpose.x + xoffset;
- expose_rect.y = xevent->xexpose.y + yoffset;
++ expose_rect.x = xevent->xexpose.x;
++ expose_rect.y = xevent->xexpose.y;
+ expose_rect.width = xevent->xexpose.width;
+ expose_rect.height = xevent->xexpose.height;
+
+ _gdk_window_process_expose (window, xevent->xexpose.serial, &expose_rect);
+ return_val = FALSE;
+ }
+
+ break;
+
+ case GraphicsExpose:
+ {
+ GdkRectangle expose_rect;
+
+ GDK_NOTE (EVENTS,
+ g_message ("graphics expose:\tdrawable: %ld",
+ xevent->xgraphicsexpose.drawable));
+
+ if (window_private == NULL)
+ {
+ return_val = FALSE;
+ break;
+ }
+
- expose_rect.x = xevent->xgraphicsexpose.x + xoffset;
- expose_rect.y = xevent->xgraphicsexpose.y + yoffset;
++ expose_rect.x = xevent->xgraphicsexpose.x;
++ expose_rect.y = xevent->xgraphicsexpose.y;
+ expose_rect.width = xevent->xgraphicsexpose.width;
+ expose_rect.height = xevent->xgraphicsexpose.height;
+
+ _gdk_window_process_expose (window, xevent->xgraphicsexpose.serial, &expose_rect);
+
+ return_val = FALSE;
+ }
+ break;
+
+ case NoExpose:
+ GDK_NOTE (EVENTS,
+ g_message ("no expose:\t\tdrawable: %ld",
+ xevent->xnoexpose.drawable));
+
+ event->no_expose.type = GDK_NO_EXPOSE;
+ event->no_expose.window = window;
+
+ break;
+
+ case VisibilityNotify:
+#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);
+ break;
+ case VisibilityPartiallyObscured:
+ g_message ("visibility notify:\twindow: %ld partial",
+ xevent->xvisibility.window);
+ break;
+ case VisibilityUnobscured:
+ g_message ("visibility notify:\twindow: %ld full",
+ xevent->xvisibility.window);
+ break;
+ }
+#endif /* G_ENABLE_DEBUG */
+
+ if (window_private == NULL)
+ {
+ return_val = FALSE;
+ break;
+ }
+
+ 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:
+ GDK_NOTE (EVENTS,
+ g_message ("create notify:\twindow: %ld x,y: %d %d w,h: %d %d b-w: %d parent: %ld ovr: %d",
+ xevent->xcreatewindow.window,
+ xevent->xcreatewindow.x,
+ xevent->xcreatewindow.y,
+ xevent->xcreatewindow.width,
+ xevent->xcreatewindow.height,
+ xevent->xcreatewindow.border_width,
+ xevent->xcreatewindow.parent,
+ xevent->xcreatewindow.override_redirect));
+ /* not really handled */
+ break;
+
+ case DestroyNotify:
+ GDK_NOTE (EVENTS,
+ g_message ("destroy notify:\twindow: %ld",
+ xevent->xdestroywindow.window));
+
+ /* Ignore DestroyNotify from SubstructureNotifyMask */
+ if (xevent->xdestroywindow.window == xevent->xdestroywindow.event)
+ {
+ event->any.type = GDK_DESTROY;
+ event->any.window = window;
+
+ return_val = window_private && !GDK_WINDOW_DESTROYED (window);
+
+ if (window && GDK_WINDOW_XID (window) != screen_x11->xroot_window)
+ gdk_window_destroy_notify (window);
+ }
+ else
+ return_val = FALSE;
+
+ break;
+
+ case UnmapNotify:
+ GDK_NOTE (EVENTS,
+ g_message ("unmap notify:\t\twindow: %ld",
+ xevent->xmap.window));
+
+ event->any.type = GDK_UNMAP;
+ event->any.window = window;
+
+ /* If we are shown (not withdrawn) and get an unmap, it means we
+ * were iconified in the X sense. If we are withdrawn, and get
+ * an unmap, it means we hid the window ourselves, so we
+ * will have already flipped the iconified bit off.
+ */
+ if (window)
+ {
+ if (GDK_WINDOW_IS_MAPPED (window))
+ gdk_synthesize_window_state (window,
+ 0,
+ GDK_WINDOW_STATE_ICONIFIED);
+
+ _gdk_xgrab_check_unmap (window, xevent->xany.serial);
+ }
+
+ break;
+
+ case MapNotify:
+ GDK_NOTE (EVENTS,
+ g_message ("map notify:\t\twindow: %ld",
+ xevent->xmap.window));
+
+ event->any.type = GDK_MAP;
+ event->any.window = window;
+
+ /* Unset iconified if it was set */
+ if (window && (((GdkWindowObject*)window)->state & GDK_WINDOW_STATE_ICONIFIED))
+ gdk_synthesize_window_state (window,
+ GDK_WINDOW_STATE_ICONIFIED,
+ 0);
+
+ break;
+
+ case ReparentNotify:
+ GDK_NOTE (EVENTS,
+ g_message ("reparent notify:\twindow: %ld x,y: %d %d parent: %ld ovr: %d",
+ xevent->xreparent.window,
+ xevent->xreparent.x,
+ xevent->xreparent.y,
+ xevent->xreparent.parent,
+ xevent->xreparent.override_redirect));
+
+ /* Not currently handled */
+ return_val = FALSE;
+ break;
+
+ case ConfigureNotify:
+ GDK_NOTE (EVENTS,
+ g_message ("configure notify:\twindow: %ld x,y: %d %d w,h: %d %d b-w: %d above: %ld ovr: %d%s",
+ xevent->xconfigure.window,
+ xevent->xconfigure.x,
+ xevent->xconfigure.y,
+ xevent->xconfigure.width,
+ xevent->xconfigure.height,
+ xevent->xconfigure.border_width,
+ xevent->xconfigure.above,
+ xevent->xconfigure.override_redirect,
+ !window
+ ? " (discarding)"
+ : GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD
+ ? " (discarding child)"
+ : xevent->xconfigure.event != xevent->xconfigure.window
+ ? " (discarding substructure)"
+ : ""));
+ if (window && GDK_WINDOW_TYPE (window) == GDK_WINDOW_ROOT)
+ {
- window_impl->width = xevent->xconfigure.width;
- window_impl->height = xevent->xconfigure.height;
++ window_private->width = xevent->xconfigure.width;
++ window_private->height = xevent->xconfigure.height;
+
++ _gdk_window_update_size (window);
+ _gdk_x11_drawable_update_size (window_private->impl);
+ _gdk_x11_screen_size_changed (screen, xevent);
+ }
+
+#if 0
+ if (window &&
+ xevent->xconfigure.event == xevent->xconfigure.window &&
+ !GDK_WINDOW_DESTROYED (window) &&
- (window_private->extension_events != 0))
++ window_private->input_window != NULL)
+ _gdk_input_configure_event (&xevent->xconfigure, window);
+#endif
+
+#ifdef HAVE_XSYNC
+ if (toplevel && display_x11->use_sync && !XSyncValueIsZero (toplevel->pending_counter_value))
+ {
+ toplevel->current_counter_value = toplevel->pending_counter_value;
+ XSyncIntToValue (&toplevel->pending_counter_value, 0);
+ }
+#endif
+
+ if (!window ||
+ xevent->xconfigure.event != xevent->xconfigure.window ||
+ GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD ||
+ GDK_WINDOW_TYPE (window) == GDK_WINDOW_ROOT)
+ 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.send_event &&
+ !xevent->xconfigure.override_redirect &&
+ !GDK_WINDOW_DESTROYED (window))
+ {
+ gint tx = 0;
+ gint ty = 0;
+ Window child_window = 0;
+
+ gdk_error_trap_push ();
+ if (XTranslateCoordinates (GDK_DRAWABLE_XDISPLAY (window),
+ GDK_DRAWABLE_XID (window),
+ screen_x11->xroot_window,
+ 0, 0,
+ &tx, &ty,
+ &child_window))
+ {
+ event->configure.x = tx;
+ event->configure.y = ty;
+ }
+ gdk_error_trap_pop ();
+ }
+ 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_impl->width = xevent->xconfigure.width;
- window_impl->height = xevent->xconfigure.height;
++ window_private->width = xevent->xconfigure.width;
++ window_private->height = xevent->xconfigure.height;
+
++ _gdk_window_update_size (window);
+ _gdk_x11_drawable_update_size (window_private->impl);
+
+ if (window_private->resize_count >= 1)
+ {
+ window_private->resize_count -= 1;
+
+ if (window_private->resize_count == 0)
+ _gdk_moveresize_configure_done (display, window);
+ }
+ }
+ break;
+
+ case PropertyNotify:
+ GDK_NOTE (EVENTS,
+ g_message ("property notify:\twindow: %ld, atom(%ld): %s%s%s",
+ xevent->xproperty.window,
+ xevent->xproperty.atom,
+ "\"",
+ gdk_x11_get_xatom_name_for_display (display, xevent->xproperty.atom),
+ "\""));
+
+ if (window_private == NULL)
+ {
+ return_val = FALSE;
+ break;
+ }
+
+ /* We compare with the serial of the last time we mapped the
+ * window to avoid refetching properties that we set ourselves
+ */
+ if (toplevel &&
+ xevent->xproperty.serial >= toplevel->map_serial)
+ {
+ if (xevent->xproperty.atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE"))
+ gdk_check_wm_state_changed (window);
+
+ if (xevent->xproperty.atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_DESKTOP"))
+ gdk_check_wm_desktop_changed (window);
+ }
+
+ if (window_private->event_mask & GDK_PROPERTY_CHANGE_MASK)
+ {
+ event->property.type = GDK_PROPERTY_NOTIFY;
+ event->property.window = window;
+ event->property.atom = gdk_x11_xatom_to_atom_for_display (display, xevent->xproperty.atom);
+ event->property.time = xevent->xproperty.time;
+ event->property.state = xevent->xproperty.state;
+ }
+ else
+ return_val = FALSE;
+
+ break;
+
+ case SelectionClear:
+ GDK_NOTE (EVENTS,
+ g_message ("selection clear:\twindow: %ld",
+ xevent->xproperty.window));
+
+ if (_gdk_selection_filter_clear_event (&xevent->xselectionclear))
+ {
+ event->selection.type = GDK_SELECTION_CLEAR;
+ event->selection.window = window;
+ event->selection.selection = gdk_x11_xatom_to_atom_for_display (display, xevent->xselectionclear.selection);
+ event->selection.time = xevent->xselectionclear.time;
+ }
+ else
+ return_val = FALSE;
+
+ break;
+
+ case SelectionRequest:
+ GDK_NOTE (EVENTS,
+ g_message ("selection request:\twindow: %ld",
+ xevent->xproperty.window));
+
+ event->selection.type = GDK_SELECTION_REQUEST;
+ event->selection.window = window;
+ event->selection.selection = gdk_x11_xatom_to_atom_for_display (display, xevent->xselectionrequest.selection);
+ event->selection.target = gdk_x11_xatom_to_atom_for_display (display, xevent->xselectionrequest.target);
+ event->selection.property = gdk_x11_xatom_to_atom_for_display (display, 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));
+
+ event->selection.type = GDK_SELECTION_NOTIFY;
+ event->selection.window = window;
+ event->selection.selection = gdk_x11_xatom_to_atom_for_display (display, xevent->xselection.selection);
+ event->selection.target = gdk_x11_xatom_to_atom_for_display (display, xevent->xselection.target);
+ if (xevent->xselection.property == None)
+ event->selection.property = GDK_NONE;
+ else
+ event->selection.property = gdk_x11_xatom_to_atom_for_display (display, xevent->xselection.property);
+ event->selection.time = xevent->xselection.time;
+
+ break;
+
+ case ColormapNotify:
+ GDK_NOTE (EVENTS,
+ g_message ("colormap notify:\twindow: %ld",
+ xevent->xcolormap.window));
+
+ /* Not currently handled */
+ return_val = FALSE;
+ break;
+
+ case ClientMessage:
+ {
+ GList *tmp_list;
+ GdkFilterReturn result = GDK_FILTER_CONTINUE;
+ GdkAtom message_type = gdk_x11_xatom_to_atom_for_display (display, xevent->xclient.message_type);
+
+ GDK_NOTE (EVENTS,
+ g_message ("client message:\twindow: %ld",
+ xevent->xclient.window));
+
+ tmp_list = display_x11->client_filters;
+ while (tmp_list)
+ {
+ GdkClientFilter *filter = tmp_list->data;
+ tmp_list = tmp_list->next;
+
+ if (filter->type == message_type)
+ {
+ result = (*filter->function) (xevent, event, filter->data);
+ if (result != GDK_FILTER_CONTINUE)
+ break;
+ }
+ }
+
+ 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 */
+ if (window_private == NULL)
+ {
+ return_val = FALSE;
+ }
+ else
+ {
+ event->client.type = GDK_CLIENT_EVENT;
+ event->client.window = window;
+ event->client.message_type = message_type;
+ event->client.data_format = xevent->xclient.format;
+ memcpy(&event->client.data, &xevent->xclient.data,
+ sizeof(event->client.data));
+ }
+ break;
+ }
+ }
+
+ break;
+
+ case MappingNotify:
+ GDK_NOTE (EVENTS,
+ g_message ("mapping notify"));
+
+ /* Let XLib know that there is a new keyboard mapping.
+ */
+ XRefreshKeyboardMapping (&xevent->xmapping);
+ _gdk_keymap_keys_changed (display);
+ return_val = FALSE;
+ break;
+
+ default:
+#ifdef HAVE_XFIXES
+ if (xevent->type - display_x11->xfixes_event_base == XFixesSelectionNotify)
+ {
+ XFixesSelectionNotifyEvent *selection_notify = (XFixesSelectionNotifyEvent *)xevent;
+
+ _gdk_x11_screen_process_owner_change (screen, xevent);
+
+ event->owner_change.type = GDK_OWNER_CHANGE;
+ event->owner_change.window = window;
+ event->owner_change.owner = selection_notify->owner;
+ event->owner_change.reason = selection_notify->subtype;
+ event->owner_change.selection =
+ gdk_x11_xatom_to_atom_for_display (display,
+ selection_notify->selection);
+ event->owner_change.time = selection_notify->timestamp;
+ event->owner_change.selection_time = selection_notify->selection_timestamp;
+
+ return_val = TRUE;
+ }
+ else
+#endif
+#ifdef HAVE_RANDR
+ if (xevent->type - display_x11->xrandr_event_base == RRScreenChangeNotify ||
+ xevent->type - display_x11->xrandr_event_base == RRNotify)
+ {
+ if (screen)
+ _gdk_x11_screen_size_changed (screen, xevent);
+ }
+ else
+#endif
+#if defined(HAVE_XCOMPOSITE) && defined (HAVE_XDAMAGE) && defined (HAVE_XFIXES)
+ if (display_x11->have_xdamage && window_private && window_private->composited &&
+ xevent->type == display_x11->xdamage_event_base + XDamageNotify &&
+ ((XDamageNotifyEvent *) xevent)->damage == window_impl->damage)
+ {
+ XDamageNotifyEvent *damage_event = (XDamageNotifyEvent *) xevent;
+ XserverRegion repair;
+ GdkRectangle rect;
+
+ rect.x = window_private->x + damage_event->area.x;
+ rect.y = window_private->y + damage_event->area.y;
+ rect.width = damage_event->area.width;
+ rect.height = damage_event->area.height;
+
+ repair = XFixesCreateRegion (display_x11->xdisplay,
+ &damage_event->area, 1);
+ XDamageSubtract (display_x11->xdisplay,
+ window_impl->damage,
+ repair, None);
+ XFixesDestroyRegion (display_x11->xdisplay, repair);
+
+ if (window_private->parent != NULL)
+ _gdk_window_process_expose (GDK_WINDOW (window_private->parent),
+ damage_event->serial, &rect);
+
+ return_val = TRUE;
+ }
+ else
+#endif
+ return_val = FALSE;
+ }
+
+ done:
+ if (return_val)
+ {
+ if (event->any.window)
+ g_object_ref (event->any.window);
+ }
+ else
+ {
+ /* Mark this event as having no resources to be freed */
+ event->any.window = NULL;
+ event->any.type = GDK_NOTHING;
+ }
+
+ if (window)
+ g_object_unref (window);
+
+ return return_val;
+}
+
+static void
+_gdk_event_init (GdkDisplay *display)
+{
+ GdkDisplayX11 *display_x11;
+ GdkDeviceManager *device_manager;
+
+ display_x11 = GDK_DISPLAY_X11 (display);
+ display_x11->event_source = gdk_event_source_new (display);
+
+ gdk_event_source_add_translator ((GdkEventSource *) display_x11->event_source,
+ GDK_EVENT_TRANSLATOR (display));
+
+ device_manager = gdk_device_manager_get_for_display (display);
+ gdk_event_source_add_translator ((GdkEventSource *) display_x11->event_source,
+ GDK_EVENT_TRANSLATOR (device_manager));
+}
+
+static void
+_gdk_input_init (GdkDisplay *display)
+{
+ GdkDisplayX11 *display_x11;
+ GdkDeviceManager *device_manager;
+ GList *list;
+
+ display_x11 = GDK_DISPLAY_X11 (display);
+ device_manager = gdk_device_manager_get_for_display (display);
+
+ /* Add all devices */
+ display_x11->input_devices = gdk_device_manager_get_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
+
+ list = gdk_device_manager_get_devices (device_manager, GDK_DEVICE_TYPE_SLAVE);
+ display_x11->input_devices = g_list_concat (display_x11->input_devices, list);
+
+ list = gdk_device_manager_get_devices (device_manager, GDK_DEVICE_TYPE_FLOATING);
+ display_x11->input_devices = g_list_concat (display_x11->input_devices, list);
+
+ /* Now set "core" pointer to the first master device */
+ display->core_pointer = display_x11->input_devices->data;
+}
+
/**
* gdk_display_open:
* @display_name: the name of the display to open
@@@ -1487,36 -628,24 +1509,26 @@@ gdk_display_pointer_ungrab (GdkDisplay
display_x11 = GDK_DISPLAY_X11 (display);
xdisplay = GDK_DISPLAY_XDISPLAY (display);
+
+ serial = NextRequest (xdisplay);
+#if 0
- _gdk_input_ungrab_pointer (display, time);
+ _gdk_input_ungrab_pointer (display, time_);
+#endif
- XUngrabPointer (xdisplay, time);
+ XUngrabPointer (xdisplay, time_);
XFlush (xdisplay);
- if (time == GDK_CURRENT_TIME ||
- display_x11->pointer_xgrab_time == GDK_CURRENT_TIME ||
- !XSERVER_TIME_IS_LATER (display_x11->pointer_xgrab_time, time))
- display_x11->pointer_xgrab_window = NULL;
- }
-
- /**
- * gdk_display_pointer_is_grabbed:
- * @display: a #GdkDisplay
- *
- * Test if the pointer is grabbed.
- *
- * Returns: %TRUE if an active X pointer grab is in effect
- *
- * Since: 2.2
- */
- gboolean
- gdk_display_pointer_is_grabbed (GdkDisplay *display)
- {
- g_return_val_if_fail (GDK_IS_DISPLAY (display), TRUE);
-
- return (GDK_DISPLAY_X11 (display)->pointer_xgrab_window != NULL &&
- !GDK_DISPLAY_X11 (display)->pointer_xgrab_implicit);
+ grab = _gdk_display_get_last_pointer_grab (display);
+ if (grab &&
+ (time_ == GDK_CURRENT_TIME ||
+ grab->time == GDK_CURRENT_TIME ||
+ !XSERVER_TIME_IS_LATER (grab->time, time_)))
+ {
+ grab->serial_end = serial;
+ _gdk_x11_roundtrip_async (display,
+ pointer_ungrab_callback,
+ NULL);
+ }
}
/**
diff --cc gdk/x11/gdkevents-x11.c
index fe4d862,ad5107b..4676d66
--- a/gdk/x11/gdkevents-x11.c
+++ b/gdk/x11/gdkevents-x11.c
@@@ -1841,9 -1843,8 +1846,9 @@@ gdk_event_translate (GdkDisplay *displa
if (window &&
xevent->xconfigure.event == xevent->xconfigure.window &&
!GDK_WINDOW_DESTROYED (window) &&
- (window_private->extension_events != 0))
+ window_private->input_window != NULL)
_gdk_input_configure_event (&xevent->xconfigure, window);
+#endif
#ifdef HAVE_XSYNC
if (toplevel && display_x11->use_sync && !XSyncValueIsZero (toplevel->pending_counter_value))
@@@ -2155,13 -2157,12 +2161,13 @@@
#endif
{
/* something else - (e.g., a Xinput event) */
-
+#if 0
if (window_private &&
!GDK_WINDOW_DESTROYED (window_private) &&
- (window_private->extension_events != 0))
- return_val = _gdk_input_other_event(event, xevent, window);
+ window_private->input_window)
+ return_val = _gdk_input_other_event (event, xevent, window);
else
+#endif
return_val = FALSE;
break;
@@@ -2297,42 -2296,29 +2303,46 @@@ _gdk_events_queue (GdkDisplay *display
if (XFilterEvent (&xevent, None))
continue;
}
-
- event = gdk_event_new (GDK_NOTHING);
-
- event->any.window = NULL;
- event->any.send_event = xevent.xany.send_event ? TRUE : FALSE;
- ((GdkEventPrivate *)event)->flags |= GDK_EVENT_PENDING;
+ device_manager = gdk_device_manager_get_for_display (display);
+ event = gdk_event_translator_translate (GDK_EVENT_TRANSLATOR (device_manager),
+ display, &xevent);
- node = _gdk_event_queue_append (display, event);
+ if (!event)
+ event = gdk_event_translator_translate (GDK_EVENT_TRANSLATOR (display),
+ display, &xevent);
- if (gdk_event_translate (display, event, &xevent, FALSE))
- {
- ((GdkEventPrivate *)event)->flags &= ~GDK_EVENT_PENDING;
+ if (event)
- node = _gdk_event_queue_append (display, event);
++ {
+ _gdk_windowing_got_event (display, node, event, xevent.xany.serial);
- }
++ node = _gdk_event_queue_append (display, event);
++ }
else
- {
- _gdk_event_queue_remove_link (display, node);
- g_list_free_1 (node);
- gdk_event_free (event);
- }
+ {
+ event = gdk_event_new (GDK_NOTHING);
+
+ event->any.window = NULL;
+ event->any.send_event = xevent.xany.send_event ? TRUE : FALSE;
+
+ ((GdkEventPrivate *)event)->flags |= GDK_EVENT_PENDING;
+
+ node = _gdk_event_queue_append (display, event);
+
+ if (gdk_event_translate (display, event, &xevent, FALSE))
+ {
+ ((GdkEventPrivate *)event)->flags &= ~GDK_EVENT_PENDING;
++ _gdk_windowing_got_event (display, node, event, xevent.xany.serial);
+ }
+ else
+ {
+ _gdk_event_queue_remove_link (display, node);
+ g_list_free_1 (node);
+ gdk_event_free (event);
+ }
+ }
}
}
+#endif
static gboolean
gdk_event_prepare (GSource *source,
diff --cc gdk/x11/gdkeventsource.c
index 1a4e886,0000000..eac2f4b
mode 100644,000000..100644
--- a/gdk/x11/gdkeventsource.c
+++ b/gdk/x11/gdkeventsource.c
@@@ -1,220 -1,0 +1,225 @@@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 2009 Carlos Garnacho <carlosg gnome org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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 "gdkeventsource.h"
+#include "gdkinternals.h"
+#include "gdkx.h"
+
+static gboolean gdk_event_source_prepare (GSource *source,
+ gint *timeout);
+static gboolean gdk_event_source_check (GSource *source);
+static gboolean gdk_event_source_dispatch (GSource *source,
+ GSourceFunc callback,
+ gpointer user_data);
+static void gdk_event_source_finalize (GSource *source);
+
+struct _GdkEventSource
+{
+ GSource source;
+
+ GdkDisplay *display;
+ GPollFD event_poll_fd;
+ GList *translators;
+};
+
+static GSourceFuncs event_funcs = {
+ gdk_event_source_prepare,
+ gdk_event_source_check,
+ gdk_event_source_dispatch,
+ gdk_event_source_finalize
+};
+
+static GList *event_sources = NULL;
+
+
+static GdkEvent *
+gdk_event_source_translate_event (GdkEventSource *event_source,
+ XEvent *xevent)
+{
+ GdkEvent *event = NULL;
+ GList *list = event_source->translators;
+
+ while (list && !event)
+ {
+ GdkEventTranslator *translator = list->data;
+
+ list = list->next;
+ event = gdk_event_translator_translate (translator,
+ event_source->display,
+ xevent);
+ }
+
+ return event;
+}
+
+static gboolean
+gdk_check_xpending (GdkDisplay *display)
+{
+ return XPending (GDK_DISPLAY_XDISPLAY (display));
+}
+
+static gboolean
+gdk_event_source_prepare (GSource *source,
+ gint *timeout)
+{
+ GdkDisplay *display = ((GdkEventSource*) source)->display;
+ gboolean retval;
+
+ GDK_THREADS_ENTER ();
+
+ *timeout = -1;
+ retval = (_gdk_event_queue_find_first (display) != NULL ||
+ gdk_check_xpending (display));
+
+ GDK_THREADS_LEAVE ();
+
+ return retval;
+}
+
+static gboolean
+gdk_event_source_check (GSource *source)
+{
+ GdkEventSource *event_source = (GdkEventSource*) source;
+ gboolean retval;
+
+ GDK_THREADS_ENTER ();
+
+ if (event_source->event_poll_fd.revents & G_IO_IN)
+ retval = (_gdk_event_queue_find_first (event_source->display) != NULL ||
+ gdk_check_xpending (event_source->display));
+ else
+ retval = FALSE;
+
+ GDK_THREADS_LEAVE ();
+
+ return retval;
+}
+
+void
+_gdk_events_queue (GdkDisplay *display)
+{
+ GdkEvent *event;
+ XEvent xevent;
+ Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
+ GdkEventSource *event_source;
+ GdkDisplayX11 *display_x11;
+
+ display_x11 = GDK_DISPLAY_X11 (display);
+ event_source = (GdkEventSource *) display_x11->event_source;
+
+ while (!_gdk_event_queue_find_first(display) && XPending (xdisplay))
+ {
+ XNextEvent (xdisplay, &xevent);
+
+ switch (xevent.type)
+ {
+ case KeyPress:
+ case KeyRelease:
+ break;
+ default:
+ if (XFilterEvent (&xevent, None))
+ continue;
+ }
+
+ event = gdk_event_source_translate_event (event_source, &xevent);
+
+ if (event)
- _gdk_event_queue_append (display, event);
++ {
++ GList *node;
++
++ node = _gdk_event_queue_append (display, event);
++ _gdk_windowing_got_event (display, node, event, xevent.xany.serial);
++ }
+ }
+}
+
+static gboolean
+gdk_event_source_dispatch (GSource *source,
+ GSourceFunc callback,
+ gpointer user_data)
+{
+ GdkDisplay *display = ((GdkEventSource*) source)->display;
+ GdkEvent *event;
+
+ GDK_THREADS_ENTER ();
+
+ event = gdk_display_get_event (display);
+
+ if (event)
+ {
+ if (_gdk_event_func)
+ (*_gdk_event_func) (event, _gdk_event_data);
+
+ gdk_event_free (event);
+ }
+
+ GDK_THREADS_LEAVE ();
+
+ return TRUE;
+}
+
+static void
+gdk_event_source_finalize (GSource *source)
+{
+ event_sources = g_list_remove (event_sources, source);
+}
+
+GSource *
+gdk_event_source_new (GdkDisplay *display)
+{
+ GSource *source;
+ GdkEventSource *event_source;
+ GdkDisplayX11 *display_x11;
+ int connection_number;
+
+ source = g_source_new (&event_funcs, sizeof (GdkEventSource));
+ event_source = (GdkEventSource *) source;
+ event_source->display = display;
+
+ display_x11 = GDK_DISPLAY_X11 (display);
+ connection_number = ConnectionNumber (display_x11->xdisplay);
+
+ event_source->event_poll_fd.fd = connection_number;
+ event_source->event_poll_fd.events = G_IO_IN;
+ g_source_add_poll (source, &event_source->event_poll_fd);
+
+ g_source_set_priority (source, GDK_PRIORITY_EVENTS);
+ g_source_set_can_recurse (source, TRUE);
+ g_source_attach (source, NULL);
+
+ event_sources = g_list_prepend (event_sources, source);
+
+#if 0
+ gdk_display_add_client_message_filter (display,
+ gdk_atom_intern_static_string ("WM_PROTOCOLS"),
+ gdk_wm_protocols_filter,
+ NULL);
+#endif
+
+ return source;
+}
+
+void
+gdk_event_source_add_translator (GdkEventSource *source,
+ GdkEventTranslator *translator)
+{
+ g_return_if_fail (GDK_IS_EVENT_TRANSLATOR (translator));
+
+ source->translators = g_list_prepend (source->translators, translator);
+}
diff --cc gdk/x11/gdkinputprivate.h
index 5cbd809,217e28c..0a7443b
--- a/gdk/x11/gdkinputprivate.h
+++ b/gdk/x11/gdkinputprivate.h
@@@ -97,10 -96,13 +96,15 @@@ struct _GdkDevicePrivat
#endif /* !XINPUT_NONE */
};
++#if 0
struct _GdkDeviceClass
{
GObjectClass parent_class;
};
++#endif
+
+ /* Addition used for extension_events mask */
+ #define GDK_ALL_DEVICES_MASK (1<<30)
struct _GdkInputWindow
{
diff --cc gdk/x11/gdkmain-x11.c
index 97bd920,f12c709..b42dc4b
--- a/gdk/x11/gdkmain-x11.c
+++ b/gdk/x11/gdkmain-x11.c
@@@ -228,21 -192,23 +191,27 @@@ _gdk_windowing_pointer_grab (GdkWindow
if (event_mask & (1 << (i + 1)))
xevent_mask |= _gdk_event_mask_table[i];
}
-
+
+ /* We don't want to set a native motion hint mask, as we're emulating motion
+ * hints. If we set a native one we just wouldn't get any events.
+ */
+ xevent_mask &= ~PointerMotionHintMask;
+
+#if 0
return_val = _gdk_input_grab_pointer (window,
+ native,
owner_events,
event_mask,
confine_to,
time);
+#else
+ return_val = GrabSuccess;
+#endif
- if (return_val == GrabSuccess ||
+ if (return_val == GrabSuccess ||
G_UNLIKELY (!display_x11->trusted_client && return_val == AlreadyGrabbed))
{
- if (!GDK_WINDOW_DESTROYED (window))
+ if (!GDK_WINDOW_DESTROYED (native))
{
#ifdef G_ENABLE_DEBUG
if (_gdk_debug_flags & GDK_DEBUG_NOGRABS)
diff --cc gdk/x11/gdkwindow-x11.c
index 6966229,9cd453b..e83706b
--- a/gdk/x11/gdkwindow-x11.c
+++ b/gdk/x11/gdkwindow-x11.c
@@@ -664,10 -645,7 +645,8 @@@ _gdk_window_impl_new (GdkWindow *wi
GdkWindowImplX11 *impl;
GdkDrawableImplX11 *draw_impl;
GdkScreenX11 *screen_x11;
- GdkScreen *screen;
- GdkDisplay *display;
+ GdkDeviceManager *device_manager;
- GdkVisual *visual;
+
Window xparent;
Visual *xvisual;
Display *xdisplay;
@@@ -951,11 -830,6 +831,9 @@@
if (attributes_mask & GDK_WA_TYPE_HINT)
gdk_window_set_type_hint (window, attributes->type_hint);
+
- device_manager = gdk_device_manager_get_for_display (display);
++ device_manager = gdk_device_manager_get_for_display (GDK_WINDOW_DISPLAY (window));
+ gdk_device_manager_set_window_events (device_manager, window, attributes->event_mask);
-
- return window;
}
static GdkEventMask
@@@ -6194,17 -5572,20 +5576,22 @@@ gdk_window_impl_iface_init (GdkWindowIm
iface->set_background = gdk_window_x11_set_background;
iface->set_back_pixmap = gdk_window_x11_set_back_pixmap;
iface->reparent = gdk_window_x11_reparent;
+ iface->clear_region = gdk_window_x11_clear_region;
iface->set_cursor = gdk_window_x11_set_cursor;
iface->get_geometry = gdk_window_x11_get_geometry;
- iface->get_origin = gdk_window_x11_get_origin;
- iface->shape_combine_mask = gdk_window_x11_shape_combine_mask;
+ iface->get_root_coords = gdk_window_x11_get_root_coords;
+ iface->get_pointer = gdk_window_x11_get_pointer;
+ iface->get_deskrelative_origin = gdk_window_x11_get_deskrelative_origin;
iface->shape_combine_region = gdk_window_x11_shape_combine_region;
- iface->set_child_shapes = gdk_window_x11_set_child_shapes;
- iface->merge_child_shapes = gdk_window_x11_merge_child_shapes;
+ iface->input_shape_combine_region = gdk_window_x11_input_shape_combine_region;
iface->set_static_gravities = gdk_window_x11_set_static_gravities;
- iface->get_offsets = _gdk_x11_window_get_offsets;
+ iface->queue_antiexpose = _gdk_x11_window_queue_antiexpose;
+ iface->queue_translation = _gdk_x11_window_queue_translation;
+ iface->destroy = _gdk_x11_window_destroy;
++#if 0
+ iface->input_window_destroy = _gdk_input_window_destroy;
+ iface->input_window_crossing = _gdk_input_crossing_event;
++#endif
}
#define __GDK_WINDOW_X11_C__
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]