[gtk+/xi2: 242/242] Merge branch 'master' into xi2
- From: Carlos Garnacho <carlosg src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gtk+/xi2: 242/242] Merge branch 'master' into xi2
- Date: Mon, 11 Jan 2010 14:09:52 +0000 (UTC)
commit 7e08ade7a287f99cb4fb0ebb869c68aa3449757c
Merge: f1991aa 90f72a0
Author: Carlos Garnacho <carlos gnome org>
Date: Mon Jan 11 14:59:30 2010 +0100
Merge branch 'master' into xi2
Conflicts:
gdk/gdkinput.h
gdk/x11/gdkinput-x11.c
gdk/x11/gdkinput-xfree.c
gdk/x11/gdkinput.c
gdk/x11/gdkwindow-x11.c
gtk/gtkaboutdialog.c
gtk/gtkmenushell.c
gtk/gtkwidget.h
INSTALL.in | 6 +-
Makefile.am | 3 +-
NEWS | 99 +
README.in | 18 +
autogen.sh | 2 +-
configure.in | 14 +-
demos/Makefile.am | 8 +-
demos/gtk-demo/Makefile.am | 3 +-
demos/testpixbuf-color.c | 161 +
docs/reference/gdk/gdk-sections.txt | 1 +
docs/reference/gdk/tmpl/event_structs.sgml | 2 +-
docs/reference/gdk/tmpl/input_devices.sgml | 12 +-
docs/reference/gdk/tmpl/pixmaps.sgml | 61 -
docs/reference/gtk/compiling.sgml | 15 +-
docs/reference/gtk/drawing-model.xml | 11 +-
docs/reference/gtk/glossary.xml | 5 +-
docs/reference/gtk/gtk-sections.txt | 22 +
docs/reference/gtk/migrating-GtkComboBox.sgml | 16 +-
docs/reference/gtk/tmpl/filesystem.sgml | 106 -
docs/reference/gtk/tmpl/gtkbuildable.sgml | 6 +-
docs/reference/gtk/tmpl/gtkfilechooser.sgml | 1341 --
docs/reference/gtk/tmpl/gtkicontheme.sgml | 2 +-
docs/reference/gtk/tmpl/gtkimage.sgml | 518 -
docs/reference/gtk/tmpl/gtkobject.sgml | 15 -
docs/reference/gtk/tmpl/gtkprogressbar.sgml | 6 -
docs/reference/gtk/tmpl/gtkradiobutton.sgml | 7 -
docs/reference/gtk/tmpl/gtkradiomenuitem.sgml | 8 -
docs/reference/gtk/tmpl/gtkspinbutton.sgml | 9 +-
docs/reference/gtk/tmpl/gtkstock.sgml | 1020 --
docs/reference/gtk/tmpl/gtkstyle.sgml | 9 -
docs/reference/gtk/tmpl/gtktooltips.sgml | 10 -
docs/reference/gtk/tmpl/gtkwidget.sgml | 2867 -----
docs/tools/Makefile.am | 3 +-
gdk-pixbuf/Makefile.am | 23 +
gdk-pixbuf/gdk-pixbuf-animation.c | 4 +-
gdk-pixbuf/gdk-pixbuf-io.c | 19 +
gdk-pixbuf/gdk-pixbuf.c | 4 +-
gdk-pixbuf/io-gif.c | 2 +-
gdk-pixbuf/io-ico.c | 6 +-
gdk-pixbuf/io-jpeg.c | 14 +-
gdk-pixbuf/io-png.c | 93 +-
gdk-pixbuf/io-tiff.c | 80 +-
gdk-pixbuf/pixops/pixops.c | 17 +-
gdk/Makefile.am | 47 +-
gdk/directfb/gdkdrawable-directfb.c | 4 +-
gdk/directfb/gdkevents-directfb.c | 4 +
gdk/directfb/gdkscreen-directfb.c | 8 +
gdk/gdk.c | 14 +-
gdk/gdk.symbols | 4 +-
gdk/gdkcolor.c | 4 +-
gdk/gdkdevice.c | 19 +-
gdk/gdkdisplay.c | 22 +-
gdk/gdkdisplaymanager.c | 21 +-
gdk/gdkdnd.c | 8 +-
gdk/gdkdraw.c | 6 +-
gdk/gdkevents.c | 6 +-
gdk/gdkfont.c | 4 +-
gdk/gdkkeys.c | 6 +-
gdk/gdkkeys.h | 2 +
gdk/gdkoffscreenwindow.c | 51 +-
gdk/gdkpixmap.c | 67 +
gdk/gdkregion-generic.c | 2 +-
gdk/gdkscreen.h | 1 +
gdk/gdkwindow.c | 138 +-
gdk/quartz/GdkQuartzView.c | 14 +-
gdk/quartz/GdkQuartzWindow.c | 2 +-
gdk/quartz/gdkcolor-quartz.c | 8 +-
gdk/quartz/gdkcursor-quartz.c | 6 +-
gdk/quartz/gdkevents-quartz.c | 2 +-
gdk/quartz/gdkgc-quartz.c | 20 +-
gdk/quartz/gdkkeys-quartz.c | 8 +
gdk/quartz/gdkprivate-quartz.h | 12 +-
gdk/quartz/gdkscreen-quartz.c | 10 +-
gdk/quartz/gdkwindow-quartz.c | 18 +-
gdk/quartz/gdkwindow-quartz.h | 12 +
gdk/win32/gdkdnd-win32.c | 1594 ++-
gdk/win32/gdkevents-win32.c | 192 +-
gdk/win32/gdkglobals-win32.c | 18 +-
gdk/win32/gdkinput-win32.c | 2 +-
gdk/win32/gdkinput.c | 10 +-
gdk/win32/gdkkeys-win32.c | 8 +
gdk/win32/gdkmain-win32.c | 43 +-
gdk/win32/gdkprivate-win32.h | 44 +-
gdk/win32/gdkproperty-win32.c | 5 +
gdk/win32/gdkscreen-win32.c | 8 +
gdk/win32/gdkselection-win32.c | 59 +-
gdk/win32/gdkwindow-win32.c | 2 +-
gdk/x11/gdkcursor-x11.c | 4 +-
gdk/x11/gdkdevice-core.c | 7 +-
gdk/x11/gdkdevice-xi2.c | 7 +-
gdk/x11/gdkdnd-x11.c | 8 +-
gdk/x11/gdkkeys-x11.c | 87 +-
gdk/x11/gdkproperty-x11.c | 3 +-
gdk/x11/gdkscreen-x11.c | 141 +-
gdk/x11/gdkscreen-x11.h | 1 +
gdk/x11/gdkvisual-x11.c | 4 +-
gdk/x11/gdkwindow-x11.c | 6 +-
gtk/Makefile.am | 53 +-
gtk/gtk-compose-lookaside.txt | 8 +-
gtk/gtk.h | 1 +
gtk/gtk.symbols | 19 +-
gtk/gtkaboutdialog.c | 1166 +-
gtk/gtkaccelgroup.c | 5 +-
gtk/gtkaccessible.h | 2 +-
gtk/gtkaction.c | 17 +-
gtk/gtkactiongroup.c | 16 +-
gtk/gtkactivatable.c | 12 +-
gtk/gtkassistant.c | 25 +-
gtk/gtkbin.c | 4 +-
gtk/gtkbindings.c | 2 +
gtk/gtkbuilder.c | 2 +-
gtk/gtkbutton.c | 43 +-
gtk/gtkcelleditable.c | 2 +-
gtk/gtkcelllayout.c | 4 +-
gtk/gtkcellrenderercombo.c | 6 +-
gtk/gtkcellrendererspin.c | 4 +-
gtk/gtkcellrenderertext.c | 16 +-
gtk/gtkcellview.c | 8 +-
gtk/gtkclipboard-quartz.c | 14 +-
gtk/gtkclipboard.c | 11 +-
gtk/gtkclist.c | 6 +-
gtk/gtkcolorbutton.c | 2 +-
gtk/gtkcolorsel.c | 2 +-
gtk/gtkcombobox.c | 51 +-
gtk/gtkcombobox.h | 2 -
gtk/gtkcontainer.c | 38 +-
gtk/gtkctree.c | 43 +-
gtk/gtkcustompaperunixdialog.c | 3 +-
gtk/gtkdialog.c | 16 +-
gtk/gtkdnd-quartz.c | 29 +-
gtk/gtkdnd.c | 14 +-
gtk/gtkdrawingarea.c | 4 +-
gtk/gtkeditable.c | 14 +-
gtk/gtkentry.c | 47 +-
gtk/gtkentrycompletion.c | 2 +-
gtk/gtkeventbox.c | 30 +-
gtk/gtkexpander.c | 8 +-
gtk/gtkfilechooser.c | 618 +-
gtk/gtkfilechooser.h | 51 +-
gtk/gtkfilechooserbutton.c | 3 +-
gtk/gtkfilechooserdefault.c | 2 +-
gtk/gtkfixed.c | 23 +-
gtk/gtkfixed.h | 2 +
gtk/gtkfontbutton.c | 2 +-
gtk/gtkfontsel.c | 2 +-
gtk/gtkframe.c | 4 +-
gtk/gtkhandlebox.c | 2 +-
gtk/gtkiconfactory.c | 25 +-
gtk/gtkicontheme.c | 22 +-
gtk/gtkiconview.c | 20 +-
gtk/gtkimage.c | 198 +-
gtk/gtkimage.h | 28 +
gtk/gtkimagemenuitem.c | 4 +-
gtk/gtkimcontextsimple.c | 9 +-
gtk/gtkimcontextsimpleseqs.h | 14 +-
gtk/gtkitemfactory.c | 6 +-
gtk/gtkkeyhash.c | 27 +-
gtk/gtklabel.c | 307 +-
gtk/gtklabel.h | 5 +
gtk/gtklayout.c | 4 +-
gtk/gtklinkbutton.c | 4 +-
gtk/gtkliststore.c | 18 +-
gtk/gtkmain.c | 58 +-
gtk/gtkmenu.c | 27 +-
gtk/gtkmenubar.c | 5 +-
gtk/gtkmenuitem.c | 5 +-
gtk/gtkmenushell.c | 88 +-
gtk/gtkmenushell.h | 6 +
gtk/gtkmenutoolbutton.c | 4 +-
gtk/gtkmessagedialog.c | 10 +-
gtk/gtkmisc.c | 2 +-
gtk/gtkmountoperation.c | 24 +-
gtk/gtkmountoperation.h | 5 +
gtk/gtknotebook.c | 65 +-
gtk/gtkobject.h | 22 +-
gtk/gtkoffscreenwindow.c | 315 +
gtk/gtkoffscreenwindow.h | 60 +
gtk/gtkoptionmenu.c | 2 +-
gtk/gtkpaned.c | 2 +-
gtk/gtkpapersize.c | 12 +-
gtk/gtkpixmap.c | 4 +
gtk/gtkplug.c | 16 +-
gtk/gtkprintbackend.c | 27 +-
gtk/gtkprintbackend.h | 10 +-
gtk/gtkprintcontext.c | 64 +
gtk/gtkprintcontext.h | 5 +
gtk/gtkprinter-private.h | 5 -
gtk/gtkprinter.c | 60 +-
gtk/gtkprinter.h | 5 +
gtk/gtkprinteroptionset.c | 18 +-
gtk/gtkprinteroptionwidget.c | 4 +-
gtk/gtkprintoperation-private.h | 5 +
gtk/gtkprintoperation-unix.c | 38 +-
gtk/gtkprintoperation-win32.c | 23 +-
gtk/gtkprintoperation.c | 12 +-
gtk/gtkprintsettings.c | 33 +-
gtk/gtkprintunixdialog.c | 2 +-
gtk/gtkprogressbar.c | 8 +
gtk/gtkquartz.c | 18 +-
gtk/gtkquartz.h | 4 +-
gtk/gtkradioaction.c | 2 +-
gtk/gtkradiobutton.c | 12 +
gtk/gtkradiomenuitem.c | 10 +
gtk/gtkrange.c | 4 +-
gtk/gtkrc.c | 6 +-
gtk/gtkrecentchooser.c | 6 +-
gtk/gtkrecentchooserdefault.c | 2 +-
gtk/gtkrecentmanager.c | 25 +-
gtk/gtkscalebutton.c | 4 +-
gtk/gtkscrolledwindow.c | 20 +-
gtk/gtkselection.c | 16 +-
gtk/gtksettings.c | 32 +-
gtk/gtksizegroup.c | 6 +-
gtk/gtksocket-x11.c | 19 +-
gtk/gtksocket.c | 6 +-
gtk/gtkspinbutton.c | 10 +
gtk/gtkstatusicon.c | 20 +-
gtk/gtkstock.c | 29 +-
gtk/gtkstock.h | 857 ++-
gtk/gtkstyle.c | 184 +-
gtk/gtktextbuffer.c | 14 +-
gtk/gtktextbufferrichtext.c | 4 +-
gtk/gtktextchild.c | 6 +-
gtk/gtktextiter.c | 42 +-
gtk/gtktextlayout.c | 10 +
gtk/gtktextmark.c | 4 +-
gtk/gtktexttag.c | 2 +-
gtk/gtktextview.c | 97 +-
gtk/gtktogglebutton.c | 2 +-
gtk/gtktoolbar.c | 32 +-
gtk/gtktoolbutton.c | 28 +-
gtk/gtktoolitem.c | 61 +-
gtk/gtktoolpalette.c | 9 +-
gtk/gtktoolshell.c | 2 +-
gtk/gtktooltip.c | 10 +-
gtk/gtktooltips.c | 11 +
gtk/gtktreeitem.c | 2 +-
gtk/gtktreemodel.c | 13 +-
gtk/gtktreemodelfilter.c | 2 +-
gtk/gtktreemodelfilter.h | 2 +-
gtk/gtktreeprivate.h | 2 +
gtk/gtktreeselection.c | 10 +-
gtk/gtktreestore.c | 6 +-
gtk/gtktreeview.c | 125 +-
gtk/gtktreeviewcolumn.c | 8 +-
gtk/gtkuimanager.c | 69 +-
gtk/gtkviewport.c | 10 +-
gtk/gtkwidget.c | 446 +-
gtk/gtkwidget.h | 412 +-
gtk/gtkwindow.c | 176 +-
gtk/gtkwindow.h | 3 +
gtk/tests/Makefile.am | 3 +-
gtk/tests/builder.c | 14 +-
gtk/tests/treeview.c | 2 +-
gtk/theme-bits/Makefile.am | 2 +-
m4/introspection.m4 | 96 +
modules/engines/ms-windows/msw_style.c | 4 +-
modules/engines/pixbuf/pixbuf-render.c | 48 +-
modules/input/gtkimcontextxim.c | 4 +-
modules/other/gail/gail.c | 2 +-
modules/other/gail/gailbutton.c | 2 +-
modules/other/gail/gaillabel.c | 2 +-
modules/other/gail/gailtreeview.c | 6 +-
modules/other/gail/gailwidget.c | 21 +-
modules/other/gail/gailwindow.c | 4 +-
modules/other/gail/tests/testaction.c | 2 +-
modules/other/gail/tests/testnotebook.c | 2 +-
modules/other/gail/tests/testobject.c | 2 +-
modules/other/gail/tests/testselection.c | 2 +-
modules/printbackends/cups/gtkprintbackendcups.c | 16 +-
perf/Makefile.am | 3 +-
perf/gtkwidgetprofiler.c | 2 +-
po-properties/af.po | 1235 +-
po-properties/am.po | 1228 +-
po-properties/ang.po | 1226 +-
po-properties/ar.po | 1239 +-
po-properties/as.po | 1237 +-
po-properties/ast.po | 1226 +-
po-properties/az.po | 1239 +-
po-properties/az_IR.po | 1226 +-
po-properties/be.po | 1239 +-
po-properties/be latin po | 1239 +-
po-properties/bg.po | 1235 +-
po-properties/bn.po | 1237 +-
po-properties/bn_IN.po | 1235 +-
po-properties/br.po | 1228 +-
po-properties/bs.po | 1239 +-
po-properties/ca.po | 1235 +-
po-properties/ca valencia po | 1235 +-
po-properties/crh.po | 1250 +-
po-properties/cs.po | 1237 +-
po-properties/cy.po | 3661 +++---
po-properties/da.po | 1238 +-
po-properties/de.po | 1237 +-
po-properties/dz.po | 1239 +-
po-properties/el.po | 1237 +-
po-properties/en_CA.po | 1237 +-
po-properties/en_GB.po | 1235 +-
po-properties/eo.po | 1226 +-
po-properties/es.po | 1240 +-
po-properties/et.po | 1240 +-
po-properties/eu.po | 1238 +-
po-properties/fa.po | 1231 +-
po-properties/fi.po | 1237 +-
po-properties/fr.po | 1238 +-
po-properties/ga.po | 1228 +-
po-properties/gl.po | 3551 +++---
po-properties/gu.po | 1233 +-
po-properties/he.po | 1242 +-
po-properties/hi.po | 1233 +-
po-properties/hr.po | 1239 +-
po-properties/hu.po | 1237 +-
po-properties/hy.po | 1228 +-
po-properties/ia.po | 1229 +-
po-properties/id.po | 1239 +-
po-properties/io.po | 1226 +-
po-properties/is.po | 1229 +-
po-properties/it.po | 1238 +-
po-properties/ja.po | 1237 +-
po-properties/ka.po | 1239 +-
po-properties/kn.po | 1237 +-
po-properties/ko.po | 1237 +-
po-properties/ku.po | 1227 +-
po-properties/li.po | 1239 +-
po-properties/lt.po | 1237 +-
po-properties/lv.po | 1237 +-
po-properties/mai.po | 1233 +-
po-properties/mi.po | 1228 +-
po-properties/mk.po | 1237 +-
po-properties/ml.po | 1237 +-
po-properties/mn.po | 1248 +-
po-properties/mr.po | 1235 +-
po-properties/ms.po | 1235 +-
po-properties/nb.po | 1235 +-
po-properties/nds.po | 4477 ++++----
po-properties/ne.po | 1235 +-
po-properties/nl.po | 1237 +-
po-properties/nn.po | 1235 +-
po-properties/nso.po | 1239 +-
po-properties/oc.po | 1227 +-
po-properties/or.po | 1237 +-
po-properties/pa.po | 1233 +-
po-properties/pl.po | 1237 +-
po-properties/ps.po | 1228 +-
po-properties/pt.po | 1237 +-
po-properties/pt_BR.po | 1237 +-
po-properties/ro.po | 1237 +-
po-properties/ru.po | 1237 +-
po-properties/rw.po | 1242 +-
po-properties/si.po | 1231 +-
po-properties/sk.po | 1237 +-
po-properties/sl.po |14250 +++++++++++-----------
po-properties/sq.po | 1242 +-
po-properties/sr.po | 1237 +-
po-properties/sr ije po | 1239 +-
po-properties/sr latin po | 1237 +-
po-properties/sv.po | 4881 ++++----
po-properties/ta.po | 1237 +-
po-properties/te.po | 1237 +-
po-properties/th.po | 1228 +-
po-properties/tk.po | 1229 +-
po-properties/tr.po | 1250 +-
po-properties/tt.po | 1230 +-
po-properties/uk.po | 3560 +++---
po-properties/ur.po | 1226 +-
po-properties/uz.po | 1229 +-
po-properties/uz cyrillic po | 1229 +-
po-properties/vi.po | 1235 +-
po-properties/wa.po | 1232 +-
po-properties/xh.po | 1239 +-
po-properties/yi.po | 1239 +-
po-properties/zh_CN.po | 1233 +-
po-properties/zh_HK.po | 1233 +-
po-properties/zh_TW.po | 1233 +-
po/af.po | 526 +-
po/am.po | 526 +-
po/ang.po | 526 +-
po/ar.po | 532 +-
po/as.po | 526 +-
po/ast.po |12216 ++++++++++---------
po/az.po | 526 +-
po/az_IR.po | 526 +-
po/be.po | 526 +-
po/be latin po | 526 +-
po/bg.po | 526 +-
po/bn.po | 526 +-
po/bn_IN.po | 526 +-
po/br.po | 526 +-
po/bs.po | 526 +-
po/ca.po | 526 +-
po/ca valencia po | 526 +-
po/crh.po | 526 +-
po/cs.po | 526 +-
po/cy.po | 2813 ++---
po/da.po | 526 +-
po/de.po | 526 +-
po/dz.po | 526 +-
po/el.po | 530 +-
po/en_CA.po | 526 +-
po/en_GB.po | 526 +-
po/eo.po | 526 +-
po/es.po | 391 +-
po/et.po | 52 +-
po/eu.po | 3402 ++----
po/fa.po | 526 +-
po/fi.po | 534 +-
po/fr.po | 526 +-
po/ga.po | 526 +-
po/gl.po | 2211 ++--
po/gu.po | 526 +-
po/he.po | 571 +-
po/hi.po | 526 +-
po/hr.po | 526 +-
po/hu.po | 526 +-
po/hy.po | 526 +-
po/ia.po | 526 +-
po/id.po | 526 +-
po/io.po | 526 +-
po/is.po | 526 +-
po/it.po | 526 +-
po/ja.po | 2230 ++--
po/ka.po | 526 +-
po/kn.po | 2313 ++--
po/ko.po | 526 +-
po/ku.po | 526 +-
po/li.po | 526 +-
po/lt.po | 526 +-
po/lv.po | 526 +-
po/mai.po | 526 +-
po/mi.po | 526 +-
po/mk.po | 526 +-
po/ml.po | 526 +-
po/mn.po | 526 +-
po/mr.po | 526 +-
po/ms.po | 526 +-
po/nb.po | 381 +-
po/nds.po | 2230 ++--
po/ne.po | 526 +-
po/nl.po | 526 +-
po/nn.po | 528 +-
po/nso.po | 526 +-
po/oc.po | 526 +-
po/or.po | 526 +-
po/pa.po | 2262 ++--
po/pl.po | 526 +-
po/ps.po | 526 +-
po/pt.po | 526 +-
po/pt_BR.po | 526 +-
po/ro.po | 527 +-
po/ru.po | 528 +-
po/rw.po | 526 +-
po/si.po | 526 +-
po/sk.po | 526 +-
po/sl.po | 568 +-
po/sq.po | 526 +-
po/sr.po | 526 +-
po/sr ije po | 526 +-
po/sr latin po | 526 +-
po/sv.po | 413 +-
po/ta.po | 526 +-
po/te.po | 528 +-
po/th.po | 586 +-
po/tk.po | 526 +-
po/tr.po | 526 +-
po/tt.po | 526 +-
po/uk.po | 2254 ++--
po/ur.po | 526 +-
po/uz.po | 526 +-
po/uz cyrillic po | 526 +-
po/vi.po | 614 +-
po/wa.po | 526 +-
po/xh.po | 526 +-
po/yi.po | 526 +-
po/zh_CN.po | 526 +-
po/zh_HK.po | 526 +-
po/zh_TW.po | 526 +-
tests/Makefile.am | 9 +-
tests/testassistant.c | 14 +-
tests/testdnd.c | 2 +-
tests/testgtk.c | 2 +-
tests/testoffscreenwindow.c | 94 +
tests/testxinerama.c | 48 +-
482 files changed, 126541 insertions(+), 123631 deletions(-)
---
diff --cc gdk/gdk.symbols
index eb8b47e,12967c4..1a52648
--- a/gdk/gdk.symbols
+++ b/gdk/gdk.symbols
@@@ -1087,8 -1075,8 +1088,9 @@@ gdk_screen_get_width_m
gdk_screen_get_height
gdk_screen_get_height_mm
gdk_screen_get_number
+ gdk_screen_get_primary_monitor
gdk_screen_get_root_window
+gdk_screen_get_setting
gdk_screen_get_default_colormap
gdk_screen_set_default_colormap
gdk_screen_get_n_monitors
diff --cc gdk/gdkdevice.c
index 87cb795,0000000..0e635a3
mode 100644,000000..100644
--- a/gdk/gdkdevice.c
+++ b/gdk/gdkdevice.c
@@@ -1,1100 -1,0 +1,1117 @@@
+/* 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 "config.h"
+#include "gdkdevice.h"
+#include "gdkdeviceprivate.h"
+#include "gdkintl.h"
+#include "gdkinternals.h"
+#include "gdkalias.h"
+
+#define GDK_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDK_TYPE_DEVICE, GdkDevicePrivate))
+
+typedef struct _GdkDevicePrivate GdkDevicePrivate;
+typedef struct _GdkAxisInfo GdkAxisInfo;
+
+struct _GdkAxisInfo
+{
+ GdkAtom label;
+ GdkAxisUse use;
+
+ gdouble min_axis;
+ gdouble max_axis;
+
+ gdouble min_value;
+ gdouble max_value;
+ gdouble resolution;
+};
+
+struct _GdkDevicePrivate
+{
+ GdkDeviceManager *device_manager;
+ GdkDisplay *display;
+ GdkDevice *associated;
+ GdkDeviceType type;
+ GArray *axes;
+};
+
+static void gdk_device_dispose (GObject *object);
+static void gdk_device_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gdk_device_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+
+G_DEFINE_ABSTRACT_TYPE (GdkDevice, gdk_device, G_TYPE_OBJECT)
+
+enum {
+ PROP_0,
+ PROP_DISPLAY,
+ PROP_DEVICE_MANAGER,
+ PROP_NAME,
+ PROP_ASSOCIATED_DEVICE,
+ PROP_TYPE,
+ PROP_INPUT_SOURCE,
+ PROP_INPUT_MODE,
+ PROP_HAS_CURSOR,
+ PROP_N_AXES
+};
+
+
+static void
+gdk_device_class_init (GdkDeviceClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->dispose = gdk_device_dispose;
+ object_class->set_property = gdk_device_set_property;
+ object_class->get_property = gdk_device_get_property;
+
+ g_object_class_install_property (object_class,
+ PROP_DISPLAY,
+ g_param_spec_object ("display",
+ P_("Device Display"),
+ P_("Display to which the device belongs to"),
+ GDK_TYPE_DISPLAY,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (object_class,
+ PROP_DEVICE_MANAGER,
+ g_param_spec_object ("device-manager",
+ P_("Device manager"),
+ P_("Device manager to which the device belongs to"),
+ GDK_TYPE_DEVICE_MANAGER,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (object_class,
+ PROP_NAME,
+ g_param_spec_string ("name",
+ P_("Device name"),
+ P_("Device name"),
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (object_class,
+ PROP_TYPE,
+ g_param_spec_enum ("type",
+ P_("Device type"),
+ P_("Device role in the device manager"),
+ GDK_TYPE_DEVICE_TYPE,
+ GDK_DEVICE_TYPE_MASTER,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (object_class,
+ PROP_ASSOCIATED_DEVICE,
+ g_param_spec_object ("associated-device",
+ P_("Associated device"),
+ P_("Associated pointer or keyboard to this device"),
+ GDK_TYPE_DEVICE,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (object_class,
+ PROP_INPUT_SOURCE,
+ g_param_spec_enum ("input-source",
+ P_("Input source"),
+ P_("Source type for the device"),
+ GDK_TYPE_INPUT_SOURCE,
+ GDK_SOURCE_MOUSE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (object_class,
+ PROP_INPUT_MODE,
+ g_param_spec_enum ("input-mode",
+ P_("Input mode for the device"),
+ P_("Input mode for the device"),
+ GDK_TYPE_INPUT_MODE,
+ GDK_MODE_DISABLED,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (object_class,
+ PROP_HAS_CURSOR,
+ g_param_spec_boolean ("has-cursor",
+ P_("Whether the device has cursor"),
+ P_("Whether there is a visible cursor following device motion"),
+ FALSE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (object_class,
+ PROP_N_AXES,
+ g_param_spec_uint ("n-axes",
+ P_("Number of axes in the device"),
+ P_("Number of axes in the device"),
+ 0, G_MAXUINT, 0,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+ g_type_class_add_private (object_class, sizeof (GdkDevicePrivate));
+}
+
+static void
+gdk_device_init (GdkDevice *device)
+{
+ GdkDevicePrivate *priv;
+
+ priv = GDK_DEVICE_GET_PRIVATE (device);
+ priv->axes = g_array_new (FALSE, TRUE, sizeof (GdkAxisInfo));
+}
+
+static void
+gdk_device_dispose (GObject *object)
+{
+ GdkDevicePrivate *priv;
+ GdkDevice *device;
+
+ device = GDK_DEVICE (object);
+ priv = GDK_DEVICE_GET_PRIVATE (device);
+
+ if (priv->associated)
+ {
+ _gdk_device_set_associated_device (priv->associated, NULL);
+ g_object_unref (priv->associated);
+ priv->associated = NULL;
+ }
+
+ if (priv->axes)
+ {
+ g_array_free (priv->axes, TRUE);
+ priv->axes = NULL;
+ }
+
+ g_free (device->name);
+ g_free (device->keys);
+ g_free (device->axes);
+
+ device->name = NULL;
+ device->keys = NULL;
+ device->axes = NULL;
+
+ G_OBJECT_CLASS (gdk_device_parent_class)->dispose (object);
+}
+
+static void
+gdk_device_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GdkDevice *device = GDK_DEVICE (object);
+ GdkDevicePrivate *priv = GDK_DEVICE_GET_PRIVATE (object);
+
+ switch (prop_id)
+ {
+ case PROP_DISPLAY:
+ priv->display = g_value_get_object (value);
+ break;
+ case PROP_DEVICE_MANAGER:
+ priv->device_manager = g_value_get_object (value);
+ break;
+ case PROP_NAME:
+ if (device->name)
+ g_free (device->name);
+
+ device->name = g_value_dup_string (value);
+ break;
+ case PROP_TYPE:
+ priv->type = g_value_get_enum (value);
+ break;
+ case PROP_INPUT_SOURCE:
+ device->source = g_value_get_enum (value);
+ break;
+ case PROP_INPUT_MODE:
+ gdk_device_set_mode (device, g_value_get_enum (value));
+ break;
+ case PROP_HAS_CURSOR:
+ device->has_cursor = g_value_get_boolean (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gdk_device_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GdkDevice *device = GDK_DEVICE (object);
+ GdkDevicePrivate *priv = GDK_DEVICE_GET_PRIVATE (object);
+
+ switch (prop_id)
+ {
+ case PROP_DISPLAY:
+ g_value_set_object (value, priv->display);
+ break;
+ case PROP_DEVICE_MANAGER:
+ g_value_set_object (value, priv->device_manager);
+ break;
+ case PROP_ASSOCIATED_DEVICE:
+ g_value_set_object (value, priv->associated);
+ break;
+ case PROP_NAME:
+ g_value_set_string (value,
+ device->name);
+ break;
+ case PROP_TYPE:
+ g_value_set_enum (value, priv->type);
+ break;
+ case PROP_INPUT_SOURCE:
+ g_value_set_enum (value, device->source);
+ break;
+ case PROP_INPUT_MODE:
+ g_value_set_enum (value, device->mode);
+ break;
+ case PROP_HAS_CURSOR:
+ g_value_set_boolean (value,
+ device->has_cursor);
+ break;
+ case PROP_N_AXES:
+ g_value_set_uint (value, priv->axes->len);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
++/**
++ * gdk_device_get_state:
++ * @device: a #GdkDevice.
++ * @window: a #GdkWindow.
++ * @axes: an array of doubles to store the values of the axes of @device in,
++ * or %NULL.
++ * @mask: location to store the modifiers, or %NULL.
++ *
++ * Gets the current state of a device.
++ */
+void
+gdk_device_get_state (GdkDevice *device,
+ GdkWindow *window,
+ gdouble *axes,
+ GdkModifierType *mask)
+{
+ g_return_if_fail (GDK_IS_DEVICE (device));
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ if (GDK_DEVICE_GET_CLASS (device)->get_state)
+ GDK_DEVICE_GET_CLASS (device)->get_state (device, window, axes, mask);
+}
+
+/**
+ * gdk_device_get_history:
+ * @device: a #GdkDevice
+ * @window: the window with respect to which which the event coordinates will be reported
+ * @start: starting timestamp for range of events to return
+ * @stop: ending timestamp for the range of events to return
- * @events: location to store a newly-allocated array of #GdkTimeCoord, or %NULL
++ * @events: (array length=n_events) (out) (transfer none): location to store a newly-allocated array of #GdkTimeCoord, or %NULL
+ * @n_events: location to store the length of @events, or %NULL
+ *
+ * Obtains the motion history for a device; given a starting and
+ * ending timestamp, return all events in the motion history for
+ * the device in the given range of time. Some windowing systems
+ * do not support motion history, in which case, %FALSE will
+ * be returned. (This is not distinguishable from the case where
+ * motion history is supported and no events were found.)
+ *
+ * Return value: %TRUE if the windowing system supports motion history and
+ * at least one event was found.
+ **/
+gboolean
+gdk_device_get_history (GdkDevice *device,
+ GdkWindow *window,
+ guint32 start,
+ guint32 stop,
+ GdkTimeCoord ***events,
+ guint *n_events)
+{
+ g_return_val_if_fail (GDK_IS_DEVICE (device), FALSE);
+ g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
+
+ if (!GDK_DEVICE_GET_CLASS (device)->get_history)
+ return FALSE;
+
+ return GDK_DEVICE_GET_CLASS (device)->get_history (device, window,
+ start, stop,
+ events, n_events);
+}
+
+GdkTimeCoord **
+_gdk_device_allocate_history (GdkDevice *device,
+ guint n_events)
+{
+ GdkTimeCoord **result = g_new (GdkTimeCoord *, n_events);
+ gint i;
+
+ for (i = 0; i < n_events; i++)
+ result[i] = g_malloc (sizeof (GdkTimeCoord) -
+ sizeof (double) * (GDK_MAX_TIMECOORD_AXES - device->num_axes));
+ return result;
+}
+
++/**
++ * gdk_device_free_history:
++ * @events: (inout) (transfer none): an array of #GdkTimeCoord.
++ * @n_events: the length of the array.
++ *
++ * Frees an array of #GdkTimeCoord that was returned by gdk_device_get_history().
++ */
+void
+gdk_device_free_history (GdkTimeCoord **events,
+ gint n_events)
+{
+ gint i;
+
+ for (i = 0; i < n_events; i++)
+ g_free (events[i]);
+
+ g_free (events);
+}
+
+void
+gdk_device_set_source (GdkDevice *device,
+ GdkInputSource source)
+{
+ g_return_if_fail (GDK_IS_DEVICE (device));
+
+ device->source = source;
+}
+
+gboolean
+gdk_device_set_mode (GdkDevice *device,
+ GdkInputMode mode)
+{
+ g_return_val_if_fail (GDK_IS_DEVICE (device), FALSE);
+
+ if (device->mode == mode)
+ return TRUE;
+
+ if (mode == GDK_MODE_DISABLED &&
+ gdk_device_get_device_type (device) == GDK_DEVICE_TYPE_MASTER)
+ return FALSE;
+
+ /* FIXME: setting has_cursor when mode is window? */
+
+ device->mode = mode;
+ g_object_notify (G_OBJECT (device), "input-mode");
+
+ if (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER)
+ _gdk_input_check_extension_events (device);
+
+ return TRUE;
+}
+
+void
+gdk_device_set_key (GdkDevice *device,
+ guint index,
+ guint keyval,
+ GdkModifierType modifiers)
+{
+ g_return_if_fail (GDK_IS_DEVICE (device));
+ g_return_if_fail (index < device->num_keys);
+
+ device->keys[index].keyval = keyval;
+ device->keys[index].modifiers = modifiers;
+}
+
+void
+gdk_device_set_axis_use (GdkDevice *device,
+ guint index,
+ GdkAxisUse use)
+{
+ GdkDevicePrivate *priv;
+ GdkAxisInfo *info;
+
+ g_return_if_fail (GDK_IS_DEVICE (device));
+ g_return_if_fail (index < device->num_axes);
+
+ priv = GDK_DEVICE_GET_PRIVATE (device);
+ info = &g_array_index (priv->axes, GdkAxisInfo, index);
+ info->use = use;
+
+ device->axes[index].use = use;
+
+ switch (use)
+ {
+ case GDK_AXIS_X:
+ case GDK_AXIS_Y:
+ device->axes[index].min = info->min_axis = 0;
+ device->axes[index].max = info->max_axis = 0;
+ break;
+ case GDK_AXIS_XTILT:
+ case GDK_AXIS_YTILT:
+ device->axes[index].min = info->min_axis = -1;
+ device->axes[index].max = info->max_axis = 1;
+ break;
+ default:
+ device->axes[index].min = info->min_axis = 0;
+ device->axes[index].max = info->max_axis = 1;
+ break;
+ }
+}
+
+/**
+ * gdk_device_get_display:
+ * @device: a #GdkDevice
+ *
+ * Returns the #GdkDisplay to which @device pertains.
+ *
+ * Returns: a #GdkDisplay. This memory is owned by GTK+,
+ * and must not be freed or unreffed.
+ **/
+GdkDisplay *
+gdk_device_get_display (GdkDevice *device)
+{
+ GdkDevicePrivate *priv;
+
+ g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
+
+ priv = GDK_DEVICE_GET_PRIVATE (device);
+
+ return priv->display;
+}
+
+/**
+ * gdk_device_get_associated_device:
+ * @device: a #GdkDevice
+ *
+ * Returns the associated device to @device, if @device is of type
+ * %GDK_DEVICE_TYPE_MASTER, it will return the paired pointer or
+ * keyboard.
+ *
+ * If @device is of type %GDK_DEVICE_TYPE_SLAVE, it will return
+ * the master device to which @device is attached to.
+ *
+ * If @device is of type %GDK_DEVICE_TYPE_FLOATING, %NULL will be
+ * returned, as there is no associated device.
+ *
+ * Returns: The associated device, or %NULL
+ **/
+GdkDevice *
+gdk_device_get_associated_device (GdkDevice *device)
+{
+ GdkDevicePrivate *priv;
+
+ g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
+
+ priv = GDK_DEVICE_GET_PRIVATE (device);
+
+ return priv->associated;
+}
+
+void
+_gdk_device_set_associated_device (GdkDevice *device,
+ GdkDevice *associated)
+{
+ GdkDevicePrivate *priv;
+
+ g_return_if_fail (GDK_IS_DEVICE (device));
+ g_return_if_fail (GDK_IS_DEVICE (associated));
+
+ priv = GDK_DEVICE_GET_PRIVATE (device);
+
+ if (priv->associated == associated)
+ return;
+
+ if (priv->associated)
+ {
+ g_object_unref (priv->associated);
+ priv->associated = NULL;
+ }
+
+ if (associated)
+ priv->associated = g_object_ref (associated);
+}
+
+/**
+ * gdk_device_get_device_type:
+ * @device: a #GdkDevice
+ *
+ * Returns the device type for @device.
+ *
+ * Returns: the #GdkDeviceType for @device.
+ **/
+GdkDeviceType
+gdk_device_get_device_type (GdkDevice *device)
+{
+ GdkDevicePrivate *priv;
+
+ g_return_val_if_fail (GDK_IS_DEVICE (device), GDK_DEVICE_TYPE_MASTER);
+
+ priv = GDK_DEVICE_GET_PRIVATE (device);
+
+ return priv->type;
+}
+
+/**
+ * gdk_device_list_axes:
+ * @device: a #GdkDevice
+ *
+ * Returns a #GList of #GdkAtom<!-- -->s, containing the labels for
+ * the axes that @device currently has.
+ *
+ * Returns: A #GList of #GdkAtom<!-- -->s, free with g_list_free().
+ **/
+GList *
+gdk_device_list_axes (GdkDevice *device)
+{
+ GdkDevicePrivate *priv;
+ GList *axes = NULL;
+ gint i;
+
+ priv = GDK_DEVICE_GET_PRIVATE (device);
+
+ for (i = 0; i < priv->axes->len; i++)
+ {
+ GdkAxisInfo axis_info;
+
+ axis_info = g_array_index (priv->axes, GdkAxisInfo, i);
+ axes = g_list_prepend (axes, GDK_ATOM_TO_POINTER (axis_info.label));
+ }
+
+ return g_list_reverse (axes);
+}
+
+gboolean
+gdk_device_get_axis_value (GdkDevice *device,
+ gdouble *axes,
+ GdkAtom axis_label,
+ gdouble *value)
+{
+ GdkDevicePrivate *priv;
+ gint i;
+
+ g_return_val_if_fail (GDK_IS_DEVICE (device), FALSE);
+
+ if (axes == NULL)
+ return FALSE;
+
+ priv = GDK_DEVICE_GET_PRIVATE (device);
+
+ for (i = 0; i < priv->axes->len; i++)
+ {
+ GdkAxisInfo axis_info;
+
+ axis_info = g_array_index (priv->axes, GdkAxisInfo, i);
+
+ if (axis_info.label != axis_label)
+ continue;
+
+ if (value)
+ *value = axes[i];
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/**
+ * gdk_device_get_axis:
+ * @device: a #GdkDevice
+ * @axes: pointer to an array of axes
+ * @use: the use to look for
+ * @value: location to store the found value.
+ *
+ * Interprets an array of double as axis values for a given device,
+ * and locates the value in the array for a given axis use.
+ *
+ * Return value: %TRUE if the given axis use was found, otherwise %FALSE
+ **/
+gboolean
+gdk_device_get_axis (GdkDevice *device,
+ gdouble *axes,
+ GdkAxisUse use,
+ gdouble *value)
+{
+ GdkDevicePrivate *priv;
+ gint i;
+
+ g_return_val_if_fail (GDK_IS_DEVICE (device), FALSE);
+
+ if (axes == NULL)
+ return FALSE;
+
+ priv = GDK_DEVICE_GET_PRIVATE (device);
+
+ g_return_val_if_fail (priv->axes != NULL, FALSE);
+
+ for (i = 0; i < priv->axes->len; i++)
+ {
+ GdkAxisInfo axis_info;
+
+ axis_info = g_array_index (priv->axes, GdkAxisInfo, i);
+
+ if (axis_info.use != use)
+ continue;
+
+ if (value)
+ *value = axes[i];
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static GdkEventMask
+get_native_grab_event_mask (GdkEventMask grab_mask)
+{
+ /* Similar to the above but for pointer events only */
+ return
+ GDK_POINTER_MOTION_MASK |
+ GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
+ GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK |
+ GDK_SCROLL_MASK |
+ (grab_mask &
+ ~(GDK_POINTER_MOTION_HINT_MASK |
+ GDK_BUTTON_MOTION_MASK |
+ GDK_BUTTON1_MOTION_MASK |
+ GDK_BUTTON2_MOTION_MASK |
+ GDK_BUTTON3_MOTION_MASK));
+}
+
+/**
+ * gdk_device_grab:
+ * @device: a #GdkDevice
+ * @window: the #GdkWindow which will own the grab (the grab window)
+ * @grab_ownership:
+ * @owner_events: if %FALSE then all device events are reported with respect to
+ * @window and are only reported if selected by @event_mask. If
+ * %TRUE then pointer events for this application are reported
+ * as normal, but pointer events outside this application are
+ * reported with respect to @window and only if selected by
+ * @event_mask. In either mode, unreported events are discarded.
+ * @event_mask: specifies the event mask, which is used in accordance with
+ * @owner_events.
+ * @cursor: the cursor to display while the grab is active if the device is
+ * a pointer. If this is %NULL then the normal cursors are used for
+ * @window and its descendants, and the cursor for @window is used
+ * elsewhere.
+ * @time_: the timestamp of the event which led to this pointer grab. This
+ * usually comes from the #GdkEvent struct, though %GDK_CURRENT_TIME
+ * can be used if the time isn't known.
+ *
+ * Grabs the device so that all events coming from this device are passed to
+ * this application until the device is ungrabbed with gdk_device_ungrab(),
+ * or the window becomes unviewable. This overrides any previous grab on the device
+ * by this client.
+ *
+ * Device grabs are used for operations which need complete control over the
+ * given device events (either pointer or keyboard). For example in GTK+ this
+ * is used for Drag and Drop operations, popup menus and such.
+ *
+ * Note that if the event mask of an X window has selected both button press
+ * and button release events, then a button press event will cause an automatic
+ * pointer grab until the button is released. X does this automatically since
+ * most applications expect to receive button press and release events in pairs.
+ * It is equivalent to a pointer grab on the window with @owner_events set to
+ * %TRUE.
+ *
+ * If you set up anything at the time you take the grab that needs to be
+ * cleaned up when the grab ends, you should handle the #GdkEventGrabBroken
+ * events that are emitted when the grab ends unvoluntarily.
+ *
+ * Returns: %GDK_GRAB_SUCCESS if the grab was successful.
+ **/
+GdkGrabStatus
+gdk_device_grab (GdkDevice *device,
+ GdkWindow *window,
+ GdkGrabOwnership grab_ownership,
+ gboolean owner_events,
+ GdkEventMask event_mask,
+ GdkCursor *cursor,
+ guint32 time_)
+{
+ GdkGrabStatus res;
+ GdkWindow *native;
+
+ g_return_val_if_fail (GDK_IS_DEVICE (device), 0);
+ g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
+
+ if (_gdk_native_windows)
+ native = window;
+ else
+ native = gdk_window_get_toplevel (window);
+
+ while (((GdkWindowObject *) native)->window_type == GDK_WINDOW_OFFSCREEN)
+ {
+ native = gdk_offscreen_window_get_embedder (native);
+
+ if (native == NULL ||
+ (!_gdk_window_has_impl (native) &&
+ !gdk_window_is_viewable (native)))
+ return GDK_GRAB_NOT_VIEWABLE;
+
+ native = gdk_window_get_toplevel (native);
+ }
+
+ res = _gdk_windowing_device_grab (device,
+ window,
+ native,
+ owner_events,
+ get_native_grab_event_mask (event_mask),
+ NULL,
+ cursor,
+ time_);
+
+ if (res == GDK_GRAB_SUCCESS)
+ {
+ GdkDisplay *display;
+ gulong serial;
+
+ display = gdk_drawable_get_display (window);
+ serial = _gdk_windowing_window_get_next_serial (display);
+
+ _gdk_display_add_device_grab (display,
+ device,
+ window,
+ native,
+ grab_ownership,
+ owner_events,
+ event_mask,
+ serial,
+ time_,
+ FALSE);
+ }
+
+ return res;
+}
+
+/* Private API */
+void
+_gdk_device_reset_axes (GdkDevice *device)
+{
+ GdkDevicePrivate *priv;
+ gint i;
+
+ priv = GDK_DEVICE_GET_PRIVATE (device);
+
+ for (i = priv->axes->len - 1; i >= 0; i--)
+ g_array_remove_index (priv->axes, i);
+
+ g_object_notify (G_OBJECT (device), "n-axes");
+
+ /* This is done for backwards compatibility */
+ g_free (device->axes);
+ device->axes = NULL;
+}
+
+guint
+_gdk_device_add_axis (GdkDevice *device,
+ GdkAtom label_atom,
+ GdkAxisUse use,
+ gdouble min_value,
+ gdouble max_value,
+ gdouble resolution)
+{
+ GdkDevicePrivate *priv;
+ GdkAxisInfo axis_info;
+ guint pos;
+
+ priv = GDK_DEVICE_GET_PRIVATE (device);
+
+ axis_info.use = use;
+ axis_info.label = label_atom;
+ axis_info.min_value = min_value;
+ axis_info.max_value = max_value;
+ axis_info.resolution = resolution;
+
+ switch (use)
+ {
+ case GDK_AXIS_X:
+ case GDK_AXIS_Y:
+ axis_info.min_axis = 0;
+ axis_info.max_axis = 0;
+ break;
+ case GDK_AXIS_XTILT:
+ case GDK_AXIS_YTILT:
+ axis_info.min_axis = -1;
+ axis_info.max_axis = 1;
+ break;
+ default:
+ axis_info.min_axis = 0;
+ axis_info.max_axis = 1;
+ break;
+ }
+
+ priv->axes = g_array_append_val (priv->axes, axis_info);
+ device->num_axes = priv->axes->len;
+ pos = device->num_axes - 1;
+
+ /* This is done for backwards compatibility, since the public
+ * struct doesn't actually store the device data.
+ */
+ device->axes = g_realloc (device->axes, sizeof (GdkDeviceAxis) * priv->axes->len);
+ device->axes[pos].use = axis_info.use;
+ device->axes[pos].min = axis_info.min_axis;
+ device->axes[pos].max = axis_info.max_axis;
+
+ g_object_notify (G_OBJECT (device), "n-axes");
+
+ return pos;
+}
+
+void
+_gdk_device_set_keys (GdkDevice *device,
+ guint num_keys)
+{
+ if (device->keys)
+ g_free (device->keys);
+
+ device->num_keys = num_keys;
+ device->keys = g_new0 (GdkDeviceKey, num_keys);
+}
+
+GdkAxisInfo *
+find_axis_info (GArray *array,
+ GdkAxisUse use)
+{
+ GdkAxisInfo *info;
+ gint i;
+
+ for (i = 0; i < GDK_AXIS_LAST; i++)
+ {
+ info = &g_array_index (array, GdkAxisInfo, i);
+
+ if (info->use == use)
+ return info;
+ }
+
+ return NULL;
+}
+
+GdkAxisUse
+_gdk_device_get_axis_use (GdkDevice *device,
+ guint index)
+{
+ GdkDevicePrivate *priv;
+ GdkAxisInfo info;
+
+ priv = GDK_DEVICE_GET_PRIVATE (device);
+
+ info = g_array_index (priv->axes, GdkAxisInfo, index);
+ return info.use;
+}
+
+gboolean
+_gdk_device_translate_window_coord (GdkDevice *device,
+ GdkWindow *window,
+ guint index,
+ gdouble value,
+ gdouble *axis_value)
+{
+ GdkDevicePrivate *priv;
+ GdkAxisInfo axis_info;
+ GdkAxisInfo *axis_info_x, *axis_info_y;
+ gdouble device_width, device_height;
+ gdouble x_offset, y_offset;
+ gdouble x_scale, y_scale;
+ gdouble x_min, y_min;
+ gdouble x_resolution, y_resolution;
+ gdouble device_aspect;
+ gint window_width, window_height;
+ GdkWindowObject *window_private;
+
+ priv = GDK_DEVICE_GET_PRIVATE (device);
+
+ if (index >= priv->axes->len)
+ return FALSE;
+
+ axis_info = g_array_index (priv->axes, GdkAxisInfo, index);
+
+ if (axis_info.use != GDK_AXIS_X &&
+ axis_info.use != GDK_AXIS_Y)
+ return FALSE;
+
+ if (axis_info.use == GDK_AXIS_X)
+ {
+ axis_info_x = &axis_info;
+ axis_info_y = find_axis_info (priv->axes, GDK_AXIS_Y);
+ }
+ else
+ {
+ axis_info_x = find_axis_info (priv->axes, GDK_AXIS_X);
+ axis_info_y = &axis_info;
+ }
+
+ device_width = axis_info_x->max_value - axis_info_x->min_value;
+ device_height = axis_info_y->max_value - axis_info_y->min_value;
+
+ if (device_width > 0)
+ x_min = axis_info_x->min_value;
+ else
+ {
+ device_width = gdk_screen_get_width (gdk_drawable_get_screen (window));
+ x_min = 0;
+ }
+
+ if (device_height > 0)
+ y_min = axis_info_y->min_value;
+ else
+ {
+ device_height = gdk_screen_get_height (gdk_drawable_get_screen (window));
+ y_min = 0;
+ }
+
+ window_private = (GdkWindowObject *) window;
+ gdk_drawable_get_size (window, &window_width, &window_height);
+
+ x_resolution = axis_info_x->resolution;
+ y_resolution = axis_info_y->resolution;
+
+ /*
+ * Some drivers incorrectly report the resolution of the device
+ * as zero (in partiular linuxwacom < 0.5.3 with usb tablets).
+ * This causes the device_aspect to become NaN and totally
+ * breaks windowed mode. If this is the case, the best we can
+ * do is to assume the resolution is non-zero is equal in both
+ * directions (which is true for many devices). The absolute
+ * value of the resolution doesn't matter since we only use the
+ * ratio.
+ */
+ if (x_resolution == 0 || y_resolution == 0)
+ {
+ x_resolution = 1;
+ y_resolution = 1;
+ }
+
+ device_aspect = (device_height * y_resolution) /
+ (device_width * x_resolution);
+
+ if (device_aspect * window_width >= window_height)
+ {
+ /* device taller than window */
+ x_scale = window_width / device_width;
+ y_scale = (x_scale * x_resolution) / y_resolution;
+
+ x_offset = 0;
+ y_offset = - (device_height * y_scale - window_height) / 2;
+ }
+ else
+ {
+ /* window taller than device */
+ y_scale = window_height / device_height;
+ x_scale = (y_scale * y_resolution) / x_resolution;
+
+ y_offset = 0;
+ x_offset = - (device_width * x_scale - window_width) / 2;
+ }
+
+ if (axis_value)
+ {
+ if (axis_info.use == GDK_AXIS_X)
+ *axis_value = x_offset + x_scale * (value - x_min);
+ else
+ *axis_value = y_offset + y_scale * (value - y_min);
+ }
+
+ return TRUE;
+}
+
+gboolean
+_gdk_device_translate_screen_coord (GdkDevice *device,
+ GdkWindow *window,
+ gint window_root_x,
+ gint window_root_y,
+ guint index,
+ gdouble value,
+ gdouble *axis_value)
+{
+ GdkDevicePrivate *priv;
+ GdkAxisInfo axis_info;
+ gdouble axis_width, scale, offset;
+ GdkWindowObject *window_private;
+
+ if (device->mode != GDK_MODE_SCREEN)
+ return FALSE;
+
+ priv = GDK_DEVICE_GET_PRIVATE (device);
+
+ if (index >= priv->axes->len)
+ return FALSE;
+
+ axis_info = g_array_index (priv->axes, GdkAxisInfo, index);
+
+ if (axis_info.use != GDK_AXIS_X &&
+ axis_info.use != GDK_AXIS_Y)
+ return FALSE;
+
+ axis_width = axis_info.max_value - axis_info.min_value;
+ window_private = (GdkWindowObject *) window;
+
+ if (axis_info.use == GDK_AXIS_X)
+ {
+ if (axis_width > 0)
+ scale = gdk_screen_get_width (gdk_drawable_get_screen (window)) / axis_width;
+ else
+ scale = 1;
+
+ offset = - window_root_x - window_private->abs_x;
+ }
+ else
+ {
+ if (axis_width > 0)
+ scale = gdk_screen_get_height (gdk_drawable_get_screen (window)) / axis_width;
+ else
+ scale = 1;
+
+ offset = - window_root_y - window_private->abs_y;
+ }
+
+ if (axis_value)
+ *axis_value = offset + scale * (value - axis_info.min_value);
+
+ return TRUE;
+}
+
+gboolean
+_gdk_device_translate_axis (GdkDevice *device,
+ guint index,
+ gdouble value,
+ gdouble *axis_value)
+{
+ GdkDevicePrivate *priv;
+ GdkAxisInfo axis_info;
+ gdouble axis_width, out;
+
+ priv = GDK_DEVICE_GET_PRIVATE (device);
+
+ if (index >= priv->axes->len)
+ return FALSE;
+
+ axis_info = g_array_index (priv->axes, GdkAxisInfo, index);
+
+ if (axis_info.use == GDK_AXIS_X ||
+ axis_info.use == GDK_AXIS_Y)
+ return FALSE;
+
+ axis_width = axis_info.max_value - axis_info.min_value;
+ out = (axis_info.max_axis * (value - axis_info.min_value) +
+ axis_info.min_axis * (axis_info.max_value - value)) / axis_width;
+
+ if (axis_value)
+ *axis_value = out;
+
+ return TRUE;
+}
+
+#define __GDK_DEVICE_C__
+#include "gdkaliasdef.c"
diff --cc gdk/gdkdisplay.c
index 8174f04,34c8035..c9dc514
--- a/gdk/gdkdisplay.c
+++ b/gdk/gdkdisplay.c
@@@ -672,115 -464,14 +672,115 @@@ _gdk_display_enable_motion_hints (GdkDi
}
/**
+ * gdk_display_get_device_state:
+ * @display: a #GdkDisplay.
+ * @device: device to query status to.
+ * @screen: location to store the #GdkScreen the @device is on, or %NULL.
+ * @x: location to store root window X coordinate of @device, or %NULL.
+ * @y: location to store root window Y coordinate of @device, or %NULL.
+ * @mask: location to store current modifier mask for @device, or %NULL.
+ *
+ * Gets the current location and state of @device for a given display.
+ **/
+void
+gdk_display_get_device_state (GdkDisplay *display,
+ GdkDevice *device,
+ GdkScreen **screen,
+ gint *x,
+ gint *y,
+ GdkModifierType *mask)
+{
+ GdkScreen *tmp_screen;
+ gint tmp_x, tmp_y;
+ GdkModifierType tmp_mask;
+
+ g_return_if_fail (GDK_IS_DISPLAY (display));
+ g_return_if_fail (GDK_IS_DEVICE (device));
+
+ display->device_hooks->get_device_state (display, device, &tmp_screen, &tmp_x, &tmp_y, &tmp_mask);
+
+ if (screen)
+ *screen = tmp_screen;
+ if (x)
+ *x = tmp_x;
+ if (y)
+ *y = tmp_y;
+ if (mask)
+ *mask = tmp_mask;
+}
+
+/**
+ * gdk_display_get_window_at_device_position:
+ * @display: a #GdkDisplay.
+ * @device: #GdkDevice to query info to.
+ * @win_x: return location for the X coordinate of the device location, relative to the window origin, or %NULL.
+ * @win_y: return location for the Y coordinate of the device location, relative to the window origin, or %NULL.
+ *
+ * Obtains the window underneath @device, returning the location of the device in @win_x and @win_y. Returns
+ * %NULL if the window tree under @device is not known to GDK (for example, belongs to another application).
+ *
+ * Returns: the #GdkWindow under the device position, or %NULL.
+ **/
+GdkWindow *
+gdk_display_get_window_at_device_position (GdkDisplay *display,
+ GdkDevice *device,
+ gint *win_x,
+ gint *win_y)
+{
+ gint tmp_x, tmp_y;
+ GdkWindow *window;
+
+ g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
+ g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
+
+ window = display->device_hooks->window_at_device_position (display, device, &tmp_x, &tmp_y);
+
+ if (win_x)
+ *win_x = tmp_x;
+ if (win_y)
+ *win_y = tmp_y;
+
+ return window;
+}
+
+/**
+ * gdk_display_set_device_hooks:
+ * @display: a #GdkDisplay.
+ * @new_hooks: a table of pointers to functions for getting quantities related to all
+ * devices position, or %NULL to restore the default table.
+ *
+ * This function allows for hooking into the operation of getting the current location of any
+ * #GdkDevice on a particular #GdkDisplay. This is only useful for such low-level tools as
+ * an event recorder. Applications should never have any reason to use this facility.
+ *
+ * Returns: The previous device hook table.
+ **/
+GdkDisplayDeviceHooks *
+gdk_display_set_device_hooks (GdkDisplay *display,
+ const GdkDisplayDeviceHooks *new_hooks)
+{
+ const GdkDisplayDeviceHooks *result;
+
+ g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
+ result = display->device_hooks;
+
+ if (new_hooks)
+ display->device_hooks = new_hooks;
+ else
+ display->device_hooks = &default_device_hooks;
+
+ return (GdkDisplayDeviceHooks *) result;
+}
+
+/**
* gdk_display_get_pointer:
* @display: a #GdkDisplay
- * @screen: location to store the screen that the
+ * @screen: (allow-none): location to store the screen that the
* cursor is on, or %NULL.
- * @x: location to store root window X coordinate of pointer, or %NULL.
- * @y: location to store root window Y coordinate of pointer, or %NULL.
- * @mask: location to store current modifier mask, or %NULL
- *
+ * @x: (out): location to store root window X coordinate of pointer, or %NULL.
+ * @y: (out): location to store root window Y coordinate of pointer, or %NULL.
+ * @mask: (out): location to store current modifier mask, or %NULL
+ *
* Gets the current location of the pointer and the current modifier
* mask for a given display.
*
diff --cc gdk/gdkwindow.c
index c1a2b6a,eeaee78..fca0caa
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@@ -1266,19 -1235,9 +1273,15 @@@ get_native_grab_event_mask (GdkEventMas
GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK |
GDK_SCROLL_MASK |
(grab_mask &
- ~(GDK_POINTER_MOTION_HINT_MASK |
- GDK_BUTTON_MOTION_MASK |
- GDK_BUTTON1_MOTION_MASK |
- GDK_BUTTON2_MOTION_MASK |
- GDK_BUTTON3_MOTION_MASK));
+ ~GDK_POINTER_MOTION_HINT_MASK);
}
+static GdkEventMask
+get_native_event_mask (GdkWindowObject *private)
+{
+ return get_native_device_event_mask (private, NULL);
+}
+
/* Puts the native window in the right order wrt the other native windows
* in the hierarchy, given the position it has in the client side data.
* This is useful if some operation changed the stacking order.
diff --cc gdk/x11/gdkdevice-core.c
index 69edefb,0000000..b7744ed
mode 100644,000000..100644
--- a/gdk/x11/gdkdevice-core.c
+++ b/gdk/x11/gdkdevice-core.c
@@@ -1,498 -1,0 +1,501 @@@
+/* 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 "config.h"
+
+#include <gdk/gdkwindow.h>
+#include "gdkdevice-core.h"
+#include "gdkprivate-x11.h"
+#include "gdkx.h"
+
+static gboolean gdk_device_core_get_history (GdkDevice *device,
+ GdkWindow *window,
+ guint32 start,
+ guint32 stop,
+ GdkTimeCoord ***events,
+ guint *n_events);
+static void gdk_device_core_get_state (GdkDevice *device,
+ GdkWindow *window,
+ gdouble *axes,
+ GdkModifierType *mask);
+static void gdk_device_core_set_window_cursor (GdkDevice *device,
+ GdkWindow *window,
+ GdkCursor *cursor);
+static void gdk_device_core_warp (GdkDevice *device,
+ GdkScreen *screen,
+ gint x,
+ gint y);
+static gboolean gdk_device_core_query_state (GdkDevice *device,
+ GdkWindow *window,
+ GdkWindow **root_window,
+ GdkWindow **child_window,
+ gint *root_x,
+ gint *root_y,
+ gint *win_x,
+ gint *win_y,
+ GdkModifierType *mask);
+static GdkGrabStatus gdk_device_core_grab (GdkDevice *device,
+ GdkWindow *window,
+ gboolean owner_events,
+ GdkEventMask event_mask,
+ GdkWindow *confine_to,
+ GdkCursor *cursor,
+ guint32 time_);
+static void gdk_device_core_ungrab (GdkDevice *device,
+ guint32 time_);
+static GdkWindow * gdk_device_core_window_at_position (GdkDevice *device,
+ gint *win_x,
+ gint *win_y,
+ GdkModifierType *mask,
+ gboolean get_toplevel);
+static void gdk_device_core_select_window_events (GdkDevice *device,
+ GdkWindow *window,
+ GdkEventMask event_mask);
+
+
+G_DEFINE_TYPE (GdkDeviceCore, gdk_device_core, GDK_TYPE_DEVICE)
+
+static void
+gdk_device_core_class_init (GdkDeviceCoreClass *klass)
+{
+ GdkDeviceClass *device_class = GDK_DEVICE_CLASS (klass);
+
+ device_class->get_history = gdk_device_core_get_history;
+ device_class->get_state = gdk_device_core_get_state;
+ device_class->set_window_cursor = gdk_device_core_set_window_cursor;
+ device_class->warp = gdk_device_core_warp;
+ device_class->query_state = gdk_device_core_query_state;
+ device_class->grab = gdk_device_core_grab;
+ device_class->ungrab = gdk_device_core_ungrab;
+ device_class->window_at_position = gdk_device_core_window_at_position;
+ device_class->select_window_events = gdk_device_core_select_window_events;
+}
+
+static void
+gdk_device_core_init (GdkDeviceCore *device_core)
+{
+ GdkDevice *device;
+
+ device = GDK_DEVICE (device_core);
+
+ _gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_X, 0, 0, 1);
+ _gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_Y, 0, 0, 1);
+}
+
+static gboolean
+impl_coord_in_window (GdkWindow *window,
+ int impl_x,
+ int impl_y)
+{
+ GdkWindowObject *priv = (GdkWindowObject *) window;
+
+ if (impl_x < priv->abs_x ||
+ impl_x > priv->abs_x + priv->width)
+ return FALSE;
+
+ if (impl_y < priv->abs_y ||
+ impl_y > priv->abs_y + priv->height)
+ return FALSE;
+
+ return TRUE;
+}
+
+static gboolean
+gdk_device_core_get_history (GdkDevice *device,
+ GdkWindow *window,
+ guint32 start,
+ guint32 stop,
+ GdkTimeCoord ***events,
+ guint *n_events)
+{
+ GdkWindowObject *priv;
+ XTimeCoord *xcoords;
+ GdkTimeCoord **coords;
+ GdkWindow *impl_window;
+ int tmp_n_events;
+ int i, j;
+
+ impl_window = _gdk_window_get_impl_window (window);
+ xcoords = XGetMotionEvents (GDK_DRAWABLE_XDISPLAY (window),
+ GDK_DRAWABLE_XID (impl_window),
+ start, stop, &tmp_n_events);
+ if (!xcoords)
+ return FALSE;
+
+ priv = (GdkWindowObject *) window;
+ coords = _gdk_device_allocate_history (device, tmp_n_events);
+
+ for (i = 0, j = 0; i < tmp_n_events; i++)
+ {
+ if (impl_coord_in_window (window, xcoords[i].x, xcoords[i].y))
+ {
+ coords[j]->time = xcoords[i].time;
+ coords[j]->axes[0] = xcoords[i].x - priv->abs_x;
+ coords[j]->axes[1] = xcoords[i].y - priv->abs_y;
+ j++;
+ }
+ }
+
+ XFree (xcoords);
+
+ /* free the events we allocated too much */
+ for (i = j; i < tmp_n_events; i++)
+ {
+ g_free (coords[i]);
+ coords[i] = NULL;
+ }
+
+ tmp_n_events = j;
+
+ if (tmp_n_events == 0)
+ {
+ gdk_device_free_history (coords, tmp_n_events);
+ return FALSE;
+ }
+
+ if (n_events)
+ *n_events = tmp_n_events;
+
+ if (events)
+ *events = coords;
+ else if (coords)
+ gdk_device_free_history (coords, tmp_n_events);
+
+ return TRUE;
+}
+
+static void
+gdk_device_core_get_state (GdkDevice *device,
+ GdkWindow *window,
+ gdouble *axes,
+ GdkModifierType *mask)
+{
+ gint x_int, y_int;
+
+ gdk_window_get_pointer (window, &x_int, &y_int, mask);
+
+ if (axes)
+ {
+ axes[0] = x_int;
+ axes[1] = y_int;
+ }
+}
+
+static void
+gdk_device_core_set_window_cursor (GdkDevice *device,
+ GdkWindow *window,
+ GdkCursor *cursor)
+{
+ GdkCursorPrivate *cursor_private;
+ Cursor xcursor;
+
+ cursor_private = (GdkCursorPrivate*) cursor;
+
+ if (!cursor)
+ xcursor = None;
+ else
+ xcursor = cursor_private->xcursor;
+
+ XDefineCursor (GDK_WINDOW_XDISPLAY (window),
+ GDK_WINDOW_XID (window),
+ xcursor);
+}
+
+static void
+gdk_device_core_warp (GdkDevice *device,
+ GdkScreen *screen,
+ gint x,
+ gint y)
+{
+ Display *xdisplay;
+ Window dest;
+
+ xdisplay = GDK_DISPLAY_XDISPLAY (gdk_device_get_display (device));
+ dest = GDK_WINDOW_XWINDOW (gdk_screen_get_root_window (screen));
+
+ XWarpPointer (xdisplay, None, dest, 0, 0, 0, 0, x, y);
+}
+
+static gboolean
+gdk_device_core_query_state (GdkDevice *device,
+ GdkWindow *window,
+ GdkWindow **root_window,
+ GdkWindow **child_window,
+ gint *root_x,
+ gint *root_y,
+ gint *win_x,
+ gint *win_y,
+ GdkModifierType *mask)
+{
+ GdkDisplay *display;
+ Window xroot_window, xchild_window;
+ int xroot_x, xroot_y, xwin_x, xwin_y;
+ unsigned int xmask;
+
+ display = gdk_drawable_get_display (window);
+
+ if (!XQueryPointer (GDK_WINDOW_XDISPLAY (window),
+ GDK_WINDOW_XID (window),
+ &xroot_window,
+ &xchild_window,
+ &xroot_x,
+ &xroot_y,
+ &xwin_x,
+ &xwin_y,
+ &xmask))
+ {
+ return FALSE;
+ }
+
+ if (root_window)
+ *root_window = gdk_window_lookup_for_display (display, xroot_window);
+
+ if (child_window)
+ *child_window = gdk_window_lookup_for_display (display, xchild_window);
+
+ if (root_x)
+ *root_x = xroot_x;
+
+ if (root_y)
+ *root_y = xroot_y;
+
+ if (win_x)
+ *win_x = xwin_x;
+
+ if (win_y)
+ *win_y = xwin_y;
+
+ if (mask)
+ *mask = xmask;
+
+ return TRUE;
+}
+
+static GdkGrabStatus
+gdk_device_core_grab (GdkDevice *device,
+ GdkWindow *window,
+ gboolean owner_events,
+ GdkEventMask event_mask,
+ GdkWindow *confine_to,
+ GdkCursor *cursor,
+ guint32 time_)
+{
+ GdkDisplay *display;
+ Window xwindow, xconfine_to;
+ int status;
+
+ display = gdk_device_get_display (device);
+
+ xwindow = GDK_WINDOW_XID (window);
+
+ if (confine_to)
+ confine_to = _gdk_window_get_impl_window (confine_to);
+
+ if (!confine_to || GDK_WINDOW_DESTROYED (confine_to))
+ xconfine_to = None;
+ else
+ xconfine_to = GDK_WINDOW_XID (confine_to);
+
+ if (device->source == GDK_SOURCE_KEYBOARD)
+ {
+ /* Device is a keyboard */
+ status = XGrabKeyboard (GDK_DISPLAY_XDISPLAY (display),
+ xwindow,
+ owner_events,
+ GrabModeAsync, GrabModeAsync,
+ time_);
+ }
+ else
+ {
+ Cursor xcursor;
+ guint xevent_mask;
+ gint i;
+
+ /* Device is a pointer */
+ if (!cursor)
+ xcursor = None;
+ else
+ {
+ _gdk_x11_cursor_update_theme (cursor);
+ xcursor = ((GdkCursorPrivate *) cursor)->xcursor;
+ }
+
+ xevent_mask = 0;
+
+ for (i = 0; i < _gdk_nenvent_masks; i++)
+ {
+ 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;
+
+ status = XGrabPointer (GDK_DISPLAY_XDISPLAY (display),
+ xwindow,
+ owner_events,
+ xevent_mask,
+ GrabModeAsync, GrabModeAsync,
+ xconfine_to,
+ xcursor,
+ time_);
+ }
+
+ return gdk_x11_convert_grab_status (status);
+}
+
+static void
+gdk_device_core_ungrab (GdkDevice *device,
+ guint32 time_)
+{
+ GdkDisplay *display;
+
+ display = gdk_device_get_display (device);
+
+ if (device->source == GDK_SOURCE_KEYBOARD)
+ XUngrabKeyboard (GDK_DISPLAY_XDISPLAY (display), time_);
+ else
+ XUngrabPointer (GDK_DISPLAY_XDISPLAY (display), time_);
+}
+
+static GdkWindow *
+gdk_device_core_window_at_position (GdkDevice *device,
+ gint *win_x,
+ gint *win_y,
+ GdkModifierType *mask,
+ gboolean get_toplevel)
+{
+ GdkDisplay *display;
+ GdkScreen *screen;
+ Display *xdisplay;
+ GdkWindow *window;
+ Window xwindow, root, child, last;
+ int xroot_x, xroot_y, xwin_x, xwin_y;
+ unsigned int xmask;
+
+ last = None;
+ display = gdk_device_get_display (device);
+ screen = gdk_display_get_default_screen (display);
+
+ /* This function really only works if the mouse pointer is held still
+ * during its operation. If it moves from one leaf window to another
+ * than we'll end up with inaccurate values for win_x, win_y
+ * and the result.
+ */
+ gdk_x11_display_grab (display);
+
+ xdisplay = GDK_SCREEN_XDISPLAY (screen);
+ xwindow = GDK_SCREEN_XROOTWIN (screen);
+
+ XQueryPointer (xdisplay, xwindow,
+ &root, &child,
+ &xroot_x, &xroot_y,
+ &xwin_x, &xwin_y,
+ &xmask);
+
+ if (root == xwindow)
+ xwindow = child;
+ else
+ xwindow = root;
+
+ while (xwindow)
+ {
+ last = xwindow;
+ XQueryPointer (xdisplay, xwindow,
+ &root, &xwindow,
+ &xroot_x, &xroot_y,
+ &xwin_x, &xwin_y,
+ &xmask);
+
- if (get_toplevel &&
++ if (get_toplevel && last != root &&
+ (window = gdk_window_lookup_for_display (display, last)) != NULL &&
+ GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
- break;
++ {
++ xwindow = last;
++ break;
++ }
+ }
+
+ gdk_x11_display_ungrab (display);
+
+ window = gdk_window_lookup_for_display (display, last);
+
+ if (win_x)
+ *win_x = (window) ? xwin_x : -1;
+
+ if (win_y)
+ *win_y = (window) ? xwin_y : -1;
+
+ if (mask)
+ *mask = xmask;
+
+ return window;
+}
+
+static void
+gdk_device_core_select_window_events (GdkDevice *device,
+ GdkWindow *window,
+ GdkEventMask event_mask)
+{
+ GdkEventMask filter_mask, window_mask;
+ guint xmask = 0;
+ gint i;
+
+ window_mask = gdk_window_get_events (window);
+ filter_mask = (GDK_POINTER_MOTION_MASK &
+ GDK_POINTER_MOTION_HINT_MASK &
+ GDK_BUTTON_MOTION_MASK &
+ GDK_BUTTON1_MOTION_MASK &
+ GDK_BUTTON2_MOTION_MASK &
+ GDK_BUTTON3_MOTION_MASK &
+ GDK_BUTTON_PRESS_MASK &
+ GDK_BUTTON_RELEASE_MASK &
+ GDK_KEY_PRESS_MASK &
+ GDK_KEY_RELEASE_MASK &
+ GDK_ENTER_NOTIFY_MASK &
+ GDK_LEAVE_NOTIFY_MASK &
+ GDK_FOCUS_CHANGE_MASK &
+ GDK_PROXIMITY_IN_MASK &
+ GDK_PROXIMITY_OUT_MASK &
+ GDK_SCROLL_MASK);
+
+ /* Filter out non-device events */
+ event_mask &= filter_mask;
+
+ /* Unset device events on window mask */
+ window_mask &= ~(filter_mask);
+
+ /* Combine masks */
+ event_mask |= window_mask;
+
+ for (i = 0; i < _gdk_nenvent_masks; i++)
+ {
+ if (event_mask & (1 << (i + 1)))
+ xmask |= _gdk_event_mask_table[i];
+ }
+
+ if (GDK_WINDOW_XID (window) != GDK_WINDOW_XROOTWIN (window))
+ xmask |= StructureNotifyMask | PropertyChangeMask;
+
+ XSelectInput (GDK_WINDOW_XDISPLAY (window),
+ GDK_WINDOW_XWINDOW (window),
+ xmask);
+}
diff --cc gdk/x11/gdkdevice-xi2.c
index 331d921,0000000..c5e524e
mode 100644,000000..100644
--- a/gdk/x11/gdkdevice-xi2.c
+++ b/gdk/x11/gdkdevice-xi2.c
@@@ -1,616 -1,0 +1,619 @@@
+/* 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 "config.h"
+
+#include <X11/extensions/XInput2.h>
+#include "gdkdevice-xi2.h"
+#include "gdkintl.h"
+#include "gdkx.h"
+
+#define GDK_DEVICE_XI2_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDK_TYPE_DEVICE_XI2, GdkDeviceXI2Private))
+
+typedef struct GdkDeviceXI2Private GdkDeviceXI2Private;
+
+struct GdkDeviceXI2Private
+{
+ int device_id;
+};
+
+static void gdk_device_xi2_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void gdk_device_xi2_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+
+static void gdk_device_xi2_get_state (GdkDevice *device,
+ GdkWindow *window,
+ gdouble *axes,
+ GdkModifierType *mask);
+static void gdk_device_xi2_set_window_cursor (GdkDevice *device,
+ GdkWindow *window,
+ GdkCursor *cursor);
+static void gdk_device_xi2_warp (GdkDevice *device,
+ GdkScreen *screen,
+ gint x,
+ gint y);
+static gboolean gdk_device_xi2_query_state (GdkDevice *device,
+ GdkWindow *window,
+ GdkWindow **root_window,
+ GdkWindow **child_window,
+ gint *root_x,
+ gint *root_y,
+ gint *win_x,
+ gint *win_y,
+ GdkModifierType *mask);
+
+static GdkGrabStatus gdk_device_xi2_grab (GdkDevice *device,
+ GdkWindow *window,
+ gboolean owner_events,
+ GdkEventMask event_mask,
+ GdkWindow *confine_to,
+ GdkCursor *cursor,
+ guint32 time_);
+static void gdk_device_xi2_ungrab (GdkDevice *device,
+ guint32 time_);
+
+static GdkWindow * gdk_device_xi2_window_at_position (GdkDevice *device,
+ gint *win_x,
+ gint *win_y,
+ GdkModifierType *mask,
+ gboolean get_toplevel);
+static void gdk_device_xi2_select_window_events (GdkDevice *device,
+ GdkWindow *window,
+ GdkEventMask event_mask);
+
+
+G_DEFINE_TYPE (GdkDeviceXI2, gdk_device_xi2, GDK_TYPE_DEVICE)
+
+enum {
+ PROP_0,
+ PROP_DEVICE_ID
+};
+
+static void
+gdk_device_xi2_class_init (GdkDeviceXI2Class *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GdkDeviceClass *device_class = GDK_DEVICE_CLASS (klass);
+
+ object_class->get_property = gdk_device_xi2_get_property;
+ object_class->set_property = gdk_device_xi2_set_property;
+
+ device_class->get_state = gdk_device_xi2_get_state;
+ device_class->set_window_cursor = gdk_device_xi2_set_window_cursor;
+ device_class->warp = gdk_device_xi2_warp;
+ device_class->query_state = gdk_device_xi2_query_state;
+ device_class->grab = gdk_device_xi2_grab;
+ device_class->ungrab = gdk_device_xi2_ungrab;
+ device_class->window_at_position = gdk_device_xi2_window_at_position;
+ device_class->select_window_events = gdk_device_xi2_select_window_events;
+
+ g_object_class_install_property (object_class,
+ PROP_DEVICE_ID,
+ g_param_spec_int ("device-id",
+ P_("Device ID"),
+ P_("Device identifier"),
+ 0, G_MAXINT, 0,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ g_type_class_add_private (object_class, sizeof (GdkDeviceXI2Private));
+}
+
+static void
+gdk_device_xi2_init (GdkDeviceXI2 *device)
+{
+}
+
+static void
+gdk_device_xi2_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GdkDeviceXI2Private *priv;
+
+ priv = GDK_DEVICE_XI2_GET_PRIVATE (object);
+
+ switch (prop_id)
+ {
+ case PROP_DEVICE_ID:
+ g_value_set_int (value, priv->device_id);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gdk_device_xi2_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GdkDeviceXI2Private *priv;
+
+ priv = GDK_DEVICE_XI2_GET_PRIVATE (object);
+
+ switch (prop_id)
+ {
+ case PROP_DEVICE_ID:
+ priv->device_id = g_value_get_int (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gdk_device_xi2_get_state (GdkDevice *device,
+ GdkWindow *window,
+ gdouble *axes,
+ GdkModifierType *mask)
+{
+ GdkDeviceXI2Private *priv;
+ GdkDisplay *display;
+ XIDeviceInfo *info;
+ gint i, j, ndevices;
+
+ priv = GDK_DEVICE_XI2_GET_PRIVATE (device);
+ display = gdk_device_get_display (device);
+
+ if (axes)
+ {
+ info = XIQueryDevice(GDK_DISPLAY_XDISPLAY (display),
+ priv->device_id, &ndevices);
+
+ for (i = 0, j = 0; i < info->num_classes; i++)
+ {
+ XIAnyClassInfo *class_info = info->classes[i];
+ GdkAxisUse use;
+ gdouble value;
+
+ if (class_info->type != XIValuatorClass)
+ continue;
+
+ value = ((XIValuatorClassInfo *) class_info)->value;
+ use = _gdk_device_get_axis_use (device, j);
+
+ switch (use)
+ {
+ case GDK_AXIS_X:
+ case GDK_AXIS_Y:
+ case GDK_AXIS_IGNORE:
+ if (device->mode == GDK_MODE_WINDOW)
+ _gdk_device_translate_window_coord (device, window, j, value, &axes[j]);
+ else
+ {
+ gint root_x, root_y;
+
+ /* FIXME: Maybe root coords chaching should happen here */
+ gdk_window_get_origin (window, &root_x, &root_y);
+ _gdk_device_translate_screen_coord (device, window,
+ root_x, root_y,
+ j, value,
+ &axes[j]);
+ }
+ break;
+ default:
+ _gdk_device_translate_axis (device, j, value, &axes[j]);
+ break;
+ }
+
+ j++;
+ }
+
+ XIFreeDeviceInfo (info);
+ }
+
+ if (mask)
+ gdk_device_xi2_query_state (device, window,
+ NULL, NULL,
+ NULL, NULL,
+ NULL, NULL,
+ mask);
+}
+
+static void
+gdk_device_xi2_set_window_cursor (GdkDevice *device,
+ GdkWindow *window,
+ GdkCursor *cursor)
+{
+ GdkDeviceXI2Private *priv;
+ GdkCursorPrivate *cursor_private;
+
+ priv = GDK_DEVICE_XI2_GET_PRIVATE (device);
+
+ /* Non-master devices don't have a cursor */
+ if (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER)
+ return;
+
+ if (cursor)
+ {
+ cursor_private = (GdkCursorPrivate*) cursor;
+
+ XIDefineCursor (GDK_WINDOW_XDISPLAY (window),
+ priv->device_id,
+ GDK_WINDOW_XWINDOW (window),
+ cursor_private->xcursor);
+ }
+ else
+ XIUndefineCursor (GDK_WINDOW_XDISPLAY (window),
+ priv->device_id,
+ GDK_WINDOW_XWINDOW (window));
+}
+
+static void
+gdk_device_xi2_warp (GdkDevice *device,
+ GdkScreen *screen,
+ gint x,
+ gint y)
+{
+ GdkDeviceXI2Private *priv;
+ Window dest;
+
+ priv = GDK_DEVICE_XI2_GET_PRIVATE (device);
+ dest = GDK_WINDOW_XWINDOW (gdk_screen_get_root_window (screen));
+
+ XIWarpPointer (GDK_SCREEN_XDISPLAY (screen),
+ priv->device_id,
+ None, dest,
+ 0, 0, 0, 0, x, y);
+}
+
+static gboolean
+gdk_device_xi2_query_state (GdkDevice *device,
+ GdkWindow *window,
+ GdkWindow **root_window,
+ GdkWindow **child_window,
+ gint *root_x,
+ gint *root_y,
+ gint *win_x,
+ gint *win_y,
+ GdkModifierType *mask)
+{
+ GdkDisplay *display;
+ GdkDeviceXI2Private *priv;
+ Window xroot_window, xchild_window;
+ gdouble xroot_x, xroot_y, xwin_x, xwin_y;
+ XIButtonState button_state;
+ XIModifierState mod_state;
+ XIGroupState group_state;
+
+ if (!window || GDK_WINDOW_DESTROYED (window))
+ return FALSE;
+
+ priv = GDK_DEVICE_XI2_GET_PRIVATE (device);
+ display = gdk_drawable_get_display (window);
+
+ if (!XIQueryPointer (GDK_WINDOW_XDISPLAY (window),
+ priv->device_id,
+ GDK_WINDOW_XID (window),
+ &xroot_window,
+ &xchild_window,
+ &xroot_x,
+ &xroot_y,
+ &xwin_x,
+ &xwin_y,
+ &button_state,
+ &mod_state,
+ &group_state))
+ {
+ return FALSE;
+ }
+
+ if (root_window)
+ *root_window = gdk_window_lookup_for_display (display, xroot_window);
+
+ if (child_window)
+ *child_window = gdk_window_lookup_for_display (display, xchild_window);
+
+ if (root_x)
+ *root_x = (gint) xroot_x;
+
+ if (root_y)
+ *root_y = (gint) xroot_y;
+
+ if (win_x)
+ *win_x = (gint) xwin_x;
+
+ if (win_y)
+ *win_y = (gint) xwin_y;
+
+ if (mask)
+ *mask = gdk_device_xi2_translate_state (&mod_state, &button_state);
+
+ return TRUE;
+}
+
+static GdkGrabStatus
+gdk_device_xi2_grab (GdkDevice *device,
+ GdkWindow *window,
+ gboolean owner_events,
+ GdkEventMask event_mask,
+ GdkWindow *confine_to,
+ GdkCursor *cursor,
+ guint32 time_)
+{
+ GdkDeviceXI2Private *priv;
+ GdkDisplay *display;
+ XIEventMask mask;
+ Window xwindow;
+ Cursor xcursor;
+ int status;
+
+ priv = GDK_DEVICE_XI2_GET_PRIVATE (device);
+ display = gdk_device_get_display (device);
+
+ /* FIXME: confine_to is actually unused */
+
+ xwindow = GDK_WINDOW_XID (window);
+
+ if (!cursor)
+ xcursor = None;
+ else
+ {
+ _gdk_x11_cursor_update_theme (cursor);
+ xcursor = ((GdkCursorPrivate *) cursor)->xcursor;
+ }
+
+ mask.deviceid = priv->device_id;
+ mask.mask = gdk_device_xi2_translate_event_mask (event_mask, &mask.mask_len);
+
+ status = XIGrabDevice (GDK_DISPLAY_XDISPLAY (display),
+ priv->device_id,
+ xwindow,
+ time_,
+ xcursor,
+ GrabModeAsync, GrabModeAsync,
+ owner_events,
+ &mask);
+
+ g_free (mask.mask);
+
+ return gdk_x11_convert_grab_status (status);
+}
+
+static void
+gdk_device_xi2_ungrab (GdkDevice *device,
+ guint32 time_)
+{
+ GdkDeviceXI2Private *priv;
+ GdkDisplay *display;
+
+ priv = GDK_DEVICE_XI2_GET_PRIVATE (device);
+ display = gdk_device_get_display (device);
+
+ XIUngrabDevice (GDK_DISPLAY_XDISPLAY (display),
+ priv->device_id,
+ time_);
+}
+
+static GdkWindow *
+gdk_device_xi2_window_at_position (GdkDevice *device,
+ gint *win_x,
+ gint *win_y,
+ GdkModifierType *mask,
+ gboolean get_toplevel)
+{
+ GdkDeviceXI2Private *priv;
+ GdkDisplay *display;
+ GdkScreen *screen;
+ Display *xdisplay;
+ GdkWindow *window;
+ Window xwindow, root, child, last = None;
+ gdouble xroot_x, xroot_y, xwin_x, xwin_y;
+ XIButtonState button_state;
+ XIModifierState mod_state;
+ XIGroupState group_state;
+
+ priv = GDK_DEVICE_XI2_GET_PRIVATE (device);
+ display = gdk_device_get_display (device);
+ screen = gdk_display_get_default_screen (display);
+
+ /* This function really only works if the mouse pointer is held still
+ * during its operation. If it moves from one leaf window to another
+ * than we'll end up with inaccurate values for win_x, win_y
+ * and the result.
+ */
+ gdk_x11_display_grab (display);
+
+ xdisplay = GDK_SCREEN_XDISPLAY (screen);
+ xwindow = GDK_SCREEN_XROOTWIN (screen);
+
+ XIQueryPointer (xdisplay,
+ priv->device_id,
+ xwindow,
+ &root, &child,
+ &xroot_x, &xroot_y,
+ &xwin_x, &xwin_y,
+ &button_state,
+ &mod_state,
+ &group_state);
+
+ if (root == xwindow)
+ xwindow = child;
+ else
+ xwindow = root;
+
+ while (xwindow)
+ {
+ last = xwindow;
+ XIQueryPointer (xdisplay,
+ priv->device_id,
+ xwindow,
+ &root, &xwindow,
+ &xroot_x, &xroot_y,
+ &xwin_x, &xwin_y,
+ &button_state,
+ &mod_state,
+ &group_state);
+
- if (get_toplevel &&
++ if (get_toplevel && last != root &&
+ (window = gdk_window_lookup_for_display (display, last)) != NULL &&
+ GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
- break;
++ {
++ xwindow = last;
++ break;
++ }
+ }
+
+ gdk_x11_display_ungrab (display);
+
+ window = gdk_window_lookup_for_display (display, last);
+
+ if (win_x)
+ *win_x = (window) ? (gint) xwin_x : -1;
+
+ if (win_y)
+ *win_y = (window) ? (gint) xwin_y : -1;
+
+ if (mask)
+ *mask = gdk_device_xi2_translate_state (&mod_state, &button_state);
+
+ return window;
+}
+
+static void
+gdk_device_xi2_select_window_events (GdkDevice *device,
+ GdkWindow *window,
+ GdkEventMask event_mask)
+{
+ GdkDeviceXI2Private *priv;
+ XIEventMask evmask;
+
+ priv = GDK_DEVICE_XI2_GET_PRIVATE (device);
+
+ evmask.deviceid = priv->device_id;
+ evmask.mask = gdk_device_xi2_translate_event_mask (event_mask, &evmask.mask_len);
+
+ XISelectEvents (GDK_WINDOW_XDISPLAY (window),
+ GDK_WINDOW_XWINDOW (window),
+ &evmask, 1);
+
+ g_free (evmask.mask);
+}
+
+guchar *
+gdk_device_xi2_translate_event_mask (GdkEventMask event_mask,
+ int *len)
+{
+ guchar *mask;
+
+ *len = XIMaskLen (XI_LASTEVENT);
+ mask = g_new0 (guchar, *len);
+
+ if (event_mask & GDK_POINTER_MOTION_MASK ||
+ event_mask & GDK_POINTER_MOTION_HINT_MASK)
+ XISetMask (mask, XI_Motion);
+
+ if (event_mask & GDK_BUTTON_MOTION_MASK ||
+ event_mask & GDK_BUTTON1_MOTION_MASK ||
+ event_mask & GDK_BUTTON2_MOTION_MASK ||
+ event_mask & GDK_BUTTON3_MOTION_MASK)
+ {
+ XISetMask (mask, XI_ButtonPress);
+ XISetMask (mask, XI_ButtonRelease);
+ XISetMask (mask, XI_Motion);
+ }
+
+ if (event_mask & GDK_SCROLL_MASK)
+ {
+ XISetMask (mask, XI_ButtonPress);
+ XISetMask (mask, XI_ButtonRelease);
+ }
+
+ if (event_mask & GDK_BUTTON_PRESS_MASK)
+ XISetMask (mask, XI_ButtonPress);
+
+ if (event_mask & GDK_BUTTON_RELEASE_MASK)
+ XISetMask (mask, XI_ButtonRelease);
+
+ if (event_mask & GDK_KEY_PRESS_MASK)
+ XISetMask (mask, XI_KeyPress);
+
+ if (event_mask & GDK_KEY_RELEASE_MASK)
+ XISetMask (mask, XI_KeyRelease);
+
+ if (event_mask & GDK_ENTER_NOTIFY_MASK)
+ XISetMask (mask, XI_Enter);
+
+ if (event_mask & GDK_LEAVE_NOTIFY_MASK)
+ XISetMask (mask, XI_Leave);
+
+ if (event_mask & GDK_FOCUS_CHANGE_MASK)
+ {
+ XISetMask (mask, XI_FocusIn);
+ XISetMask (mask, XI_FocusOut);
+ }
+
+ return mask;
+}
+
+guint
+gdk_device_xi2_translate_state (XIModifierState *mods_state,
+ XIButtonState *buttons_state)
+{
+ guint state = 0;
+
+ if (mods_state)
+ state = (guint) mods_state->effective;
+
+ if (buttons_state)
+ {
+ gint len, i;
+
+ /* We're only interested in the first 5 buttons */
+ len = MIN (5, buttons_state->mask_len * 8);
+
+ for (i = 0; i < len; i++)
+ {
+ if (!XIMaskIsSet (buttons_state->mask, i))
+ continue;
+
+ switch (i)
+ {
+ case 1:
+ state |= GDK_BUTTON1_MASK;
+ break;
+ case 2:
+ state |= GDK_BUTTON2_MASK;
+ break;
+ case 3:
+ state |= GDK_BUTTON3_MASK;
+ break;
+ case 4:
+ state |= GDK_BUTTON4_MASK;
+ break;
+ case 5:
+ state |= GDK_BUTTON5_MASK;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ return state;
+}
diff --cc gtk/gtkaboutdialog.c
index ea6bfa5,346b894..2a54347
--- a/gtk/gtkaboutdialog.c
+++ b/gtk/gtkaboutdialog.c
@@@ -193,17 -192,16 +192,17 @@@ static void gtk_about_d
static void update_name_version (GtkAboutDialog *about);
static GtkIconSet * icon_set_new_from_pixbufs (GList *pixbufs);
static void follow_if_link (GtkAboutDialog *about,
- GtkTextView *text_view,
- GtkTextIter *iter);
+ GtkTextView *text_view,
+ GtkTextIter *iter);
static void set_cursor_if_appropriate (GtkAboutDialog *about,
- GtkTextView *text_view,
- gint x,
- gint y);
+ GtkTextView *text_view,
+ GdkDevice *device,
+ gint x,
+ gint y);
static void display_credits_dialog (GtkWidget *button,
- gpointer data);
+ gpointer data);
static void display_license_dialog (GtkWidget *button,
- gpointer data);
+ gpointer data);
static void close_cb (GtkAboutDialog *about);
static void default_url_hook (GtkAboutDialog *about,
const gchar *uri,
@@@ -1928,12 -1954,12 +1956,12 @@@ set_cursor_if_appropriate (GtkAboutDial
priv->hovering_over_link = hovering_over_link;
if (hovering_over_link)
- gdk_window_set_cursor (gtk_text_view_get_window (text_view, GTK_TEXT_WINDOW_TEXT), priv->hand_cursor);
+ gdk_window_set_device_cursor (gtk_text_view_get_window (text_view, GTK_TEXT_WINDOW_TEXT), device, priv->hand_cursor);
else
- gdk_window_set_cursor (gtk_text_view_get_window (text_view, GTK_TEXT_WINDOW_TEXT), priv->regular_cursor);
+ gdk_window_set_device_cursor (gtk_text_view_get_window (text_view, GTK_TEXT_WINDOW_TEXT), device, priv->regular_cursor);
}
- if (tags)
+ if (tags)
g_slist_free (tags);
}
diff --cc gtk/gtkmenu.c
index 5fedb18,55bf5d9..05a06aa
--- a/gtk/gtkmenu.c
+++ b/gtk/gtkmenu.c
@@@ -1649,76 -1614,22 +1649,88 @@@ gtk_menu_popup_for_device (GtkMen
gtk_widget_show (menu->toplevel);
if (xgrab_shell == widget)
- popup_grab_on_window (widget->window, activate_time, grab_keyboard); /* Should always succeed */
+ popup_grab_on_window (widget->window, keyboard, pointer, activate_time); /* Should always succeed */
+
gtk_grab_add (GTK_WIDGET (menu));
+
+ if (parent_menu_shell)
+ {
+ gboolean keyboard_mode;
+
+ keyboard_mode = _gtk_menu_shell_get_keyboard_mode (GTK_MENU_SHELL (parent_menu_shell));
+ _gtk_menu_shell_set_keyboard_mode (menu_shell, keyboard_mode);
+ }
+ else if (menu_shell->button == 0) /* a keynav-activated context menu */
+ _gtk_menu_shell_set_keyboard_mode (menu_shell, TRUE);
+
+ _gtk_menu_shell_update_mnemonics (menu_shell);
}
+/**
+ * gtk_menu_popup:
+ * @menu: a #GtkMenu.
+ * @parent_menu_shell: the menu shell containing the triggering menu item, or %NULL
+ * @parent_menu_item: the menu item whose activation triggered the popup, or %NULL
+ * @func: a user supplied function used to position the menu, or %NULL
+ * @data: user supplied data to be passed to @func.
+ * @button: the mouse button which was pressed to initiate the event.
+ * @activate_time: the time at which the activation event occurred.
+ *
+ * Displays a menu and makes it available for selection. Applications can use
+ * this function to display context-sensitive menus, and will typically supply
+ * %NULL for the @parent_menu_shell, @parent_menu_item, @func and @data
+ * parameters. The default menu positioning function will position the menu
+ * at the current mouse cursor position.
+ *
+ * The @button parameter should be the mouse button pressed to initiate
+ * the menu popup. If the menu popup was initiated by something other than
+ * a mouse button press, such as a mouse button release or a keypress,
+ * @button should be 0.
+ *
+ * The @activate_time parameter is used to conflict-resolve initiation of
+ * concurrent requests for mouse/keyboard grab requests. To function
+ * properly, this needs to be the time stamp of the user event (such as
+ * a mouse click or key press) that caused the initiation of the popup.
+ * Only if no such event is available, gtk_get_current_event_time() can
+ * be used instead.
+ */
+void
+gtk_menu_popup (GtkMenu *menu,
+ GtkWidget *parent_menu_shell,
+ GtkWidget *parent_menu_item,
+ GtkMenuPositionFunc func,
+ gpointer data,
+ guint button,
+ guint32 activate_time)
+{
+ GdkDevice *device;
+
+ g_return_if_fail (GTK_IS_MENU (menu));
+
+ device = gtk_get_current_event_device ();
+
+ if (!device)
+ {
+ GdkDisplay *display;
+ GdkDeviceManager *device_manager;
+ GList *devices;
+
+ display = gtk_widget_get_display (GTK_WIDGET (menu));
+ device_manager = gdk_display_get_device_manager (display);
+ devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
+
+ device = devices->data;
+
+ g_list_free (devices);
+ }
+
+ gtk_menu_popup_for_device (menu, device,
+ parent_menu_shell,
+ parent_menu_item,
+ func, data,
+ button, activate_time);
+}
+
void
gtk_menu_popdown (GtkMenu *menu)
{
diff --cc gtk/gtkmenushell.c
index 21f040f,c9b8949..ea686a4
--- a/gtk/gtkmenushell.c
+++ b/gtk/gtkmenushell.c
@@@ -994,15 -1068,16 +1071,19 @@@ gtk_real_menu_shell_deactivate (GtkMenu
}
if (menu_shell->have_xgrab)
{
- GdkDisplay *display = gtk_widget_get_display (GTK_WIDGET (menu_shell));
+ GtkMenuShellPrivate *priv = GTK_MENU_SHELL_GET_PRIVATE (menu_shell);
+
+ gdk_device_ungrab (priv->grab_pointer, GDK_CURRENT_TIME);
+ gdk_device_ungrab (priv->grab_keyboard, GDK_CURRENT_TIME);
menu_shell->have_xgrab = FALSE;
- gdk_display_pointer_ungrab (display, GDK_CURRENT_TIME);
- gdk_display_keyboard_ungrab (display, GDK_CURRENT_TIME);
+ priv->grab_pointer = NULL;
+ priv->grab_keyboard = NULL;
}
+
+ menu_shell->keyboard_mode = FALSE;
+
+ _gtk_menu_shell_update_mnemonics (menu_shell);
}
}
diff --cc gtk/gtkwidget.h
index 83eb961,1417fda..7464198
--- a/gtk/gtkwidget.h
+++ b/gtk/gtkwidget.h
@@@ -72,15 -116,9 +117,10 @@@ typedef enu
GTK_COMPOSITE_CHILD = 1 << 17,
GTK_NO_REPARENT = 1 << 18,
GTK_APP_PAINTABLE = 1 << 19,
-
- /* the widget when focused will receive the default action and have
- * HAS_DEFAULT set even if there is a different widget set as default
- */
GTK_RECEIVES_DEFAULT = 1 << 20,
-
GTK_DOUBLE_BUFFERED = 1 << 21,
- GTK_NO_SHOW_ALL = 1 << 22
+ GTK_NO_SHOW_ALL = 1 << 22,
+ GTK_MULTIDEVICE = 1 << 23
} GtkWidgetFlags;
/* Kinds of widget-specific help */
@@@ -148,12 -422,38 +424,39 @@@ typedef struct _GtkWidgetShapeInfo GtkW
typedef struct _GtkClipboard GtkClipboard;
typedef struct _GtkTooltip GtkTooltip;
typedef struct _GtkWindow GtkWindow;
+typedef struct _GtkMultiDeviceEvent GtkMultiDeviceEvent;
- typedef void (*GtkCallback) (GtkWidget *widget,
- gpointer data);
- /* A requisition is a desired amount of space which a
- * widget may request.
+ /**
+ * GtkAllocation:
+ * @x: the X position of the widget's area relative to its parents allocation.
+ * @y: the Y position of the widget's area relative to its parents allocation.
+ * @width: the width of the widget's allocated area.
+ * @height: the height of the widget's allocated area.
+ *
+ * A <structname>GtkAllocation</structname> of a widget represents region which has been allocated to the
+ * widget by its parent. It is a subregion of its parents allocation. See
+ * <xref linkend="size-allocation"/> for more information.
+ */
+ typedef GdkRectangle GtkAllocation;
+
+ /**
+ * GtkCallback:
+ * @widget: the widget to operate on
+ * @data: user-supplied data
+ *
+ * The type of the callback functions used for e.g. iterating over
+ * the children of a container, see gtk_container_foreach().
+ */
+ typedef void (*GtkCallback) (GtkWidget *widget,
+ gpointer data);
+
+ /**
+ * GtkRequisition:
+ * @width: the widget's desired width
+ * @height: the widget's desired height
+ *
+ * A <structname>GtkRequisition</structname> represents the desired size of a widget. See
+ * <xref linkend="size-requisition"/> for more information.
*/
struct _GtkRequisition
{
@@@ -687,21 -989,40 +1008,50 @@@ GtkClipboard *gtk_widget_get_clipboar
GdkPixmap * gtk_widget_get_snapshot (GtkWidget *widget,
GdkRectangle *clip_rect);
+/* Multidevice support */
+void gtk_widget_set_support_multidevice (GtkWidget *widget,
+ gboolean support_multidevice);
+GtkDeviceGroup * gtk_widget_get_group_for_device (GtkWidget *widget,
+ GdkDevice *device);
+GtkDeviceGroup * gtk_widget_create_device_group (GtkWidget *widget);
+void gtk_widget_remove_device_group (GtkWidget *widget,
+ GtkDeviceGroup *group);
+
+
#ifndef GTK_DISABLE_DEPRECATED
+
+ /**
+ * gtk_widget_set_visual:
+ * @widget: a #GtkWidget
+ * @visual: a visual
+ *
+ * This function is deprecated; it does nothing.
+ */
#define gtk_widget_set_visual(widget,visual) ((void) 0)
+
+ /**
+ * gtk_widget_push_visual:
+ * @visual: a visual
+ *
+ * This function is deprecated; it does nothing.
+ */
#define gtk_widget_push_visual(visual) ((void) 0)
+
+ /**
+ * gtk_widget_pop_visual:
+ *
+ * This function is deprecated; it does nothing.
+ */
#define gtk_widget_pop_visual() ((void) 0)
+
+ /**
+ * gtk_widget_set_default_visual:
+ * @visual: a visual
+ *
+ * This function is deprecated; it does nothing.
+ */
#define gtk_widget_set_default_visual(visual) ((void) 0)
+
#endif /* GTK_DISABLE_DEPRECATED */
/* Accessibility support */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]