diff options
author | Caolán McNamara <caolanm@redhat.com> | 2019-08-13 10:37:50 +0100 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2019-09-30 16:53:32 +0200 |
commit | 1ae450504cf57457f9702684b1517fda1dd3c481 (patch) | |
tree | 2b1fc3870594dcc01217e3e406322ab084e258ef | |
parent | 25ca657f8d0f1febaf0d5984bc862f3072ad197b (diff) |
drop gtk2 support
Change-Id: Ie838cabfecfef7e3225c1555536d5c9cf3b43f15
Reviewed-on: https://gerrit.libreoffice.org/77405
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
125 files changed, 11741 insertions, 22179 deletions
diff --git a/Repository.mk b/Repository.mk index 8068e52572bc..965889197a9a 100644 --- a/Repository.mk +++ b/Repository.mk @@ -224,14 +224,6 @@ $(eval $(call gb_Helper_register_executables_for_install,OOO,python, \ ) \ )) -ifeq ($(USING_X11), TRUE) -$(eval $(call gb_Helper_register_executables_for_install,OOO,gnome, \ - $(if $(ENABLE_GTK),\ - xid-fullscreen-on-all-monitors \ - ) \ -)) -endif - ifneq ($(ENABLE_POPPLER),) $(eval $(call gb_Helper_register_executables_for_install,OOO,pdfimport, \ xpdfimport \ @@ -290,7 +282,6 @@ $(eval $(call gb_Helper_register_libraries_for_install,OOOLIBS,onlineupdate, \ $(eval $(call gb_Helper_register_libraries_for_install,OOOLIBS,gnome, \ $(if $(ENABLE_EVOAB2),evoab) \ - $(if $(ENABLE_GTK),vclplug_gtk) \ $(if $(ENABLE_GTK3),vclplug_gtk3) \ $(if $(ENABLE_GIO),losessioninstall) \ $(if $(ENABLE_GIO),ucpgio1) \ diff --git a/RepositoryExternal.mk b/RepositoryExternal.mk index 57f66b8f344a..4d99f79e86ec 100644 --- a/RepositoryExternal.mk +++ b/RepositoryExternal.mk @@ -2605,34 +2605,6 @@ gb_LinkTarget__use_avahi := endif # ENABLE_AVAHI - -define gb_LinkTarget__use_gtk -$(call gb_LinkTarget_set_include,$(1),\ - $$(INCLUDE) \ - $(GTK_CFLAGS) \ -) - -$(call gb_LinkTarget_add_libs,$(1),$(GTK_LIBS)) - -ifeq ($(ENABLE_GTK_PRINT),TRUE) - -$(call gb_LinkTarget_add_defs,$(1),-DENABLE_GTK_PRINT) - -$(call gb_LinkTarget_set_include,$(1),\ - $$(INCLUDE) \ - $(GTK_PRINT_CFLAGS) \ -) - -$(call gb_LinkTarget_add_libs,$(1),$(GTK_PRINT_LIBS)) - -endif - -endef - -define gb_LinkTarget__use_gthread -$(call gb_LinkTarget_add_libs,$(1),$(GTHREAD_LIBS)) -endef - ifeq ($(ENABLE_CUPS),TRUE) define gb_LinkTarget__use_cups diff --git a/bin/check-elf-dynamic-objects b/bin/check-elf-dynamic-objects index 5492aafaca34..f64044dd1e49 100755 --- a/bin/check-elf-dynamic-objects +++ b/bin/check-elf-dynamic-objects @@ -93,7 +93,6 @@ x11whitelist="libX11.so.6 libXext.so.6 libSM.so.6 libICE.so.6 libXinerama.so.1 l openglwhitelist="libGL.so.1" giowhitelist="libgio-2.0.so.0 libgobject-2.0.so.0 libgmodule-2.0.so.0 libgthread-2.0.so.0 libglib-2.0.so.0 libdbus-glib-1.so.2 libdbus-1.so.3" gstreamerwhitelist="libgstaudio-1.0.so.0 libgstpbutils-1.0.so.0 libgstvideo-1.0.so.0 libgstbase-1.0.so.0 libgstreamer-1.0.so.0" -gtk2whitelist="libgtk-x11-2.0.so.0 libgdk-x11-2.0.so.0 libpangocairo-1.0.so.0 libfribidi.so.0 libatk-1.0.so.0 libcairo.so.2 libgio-2.0.so.0 libpangoft2-1.0.so.0 libpango-1.0.so.0 libfontconfig.so.1 libfreetype.so.6 libgdk_pixbuf-2.0.so.0 libgobject-2.0.so.0 libglib-2.0.so.0 libgmodule-2.0.so.0 libgthread-2.0.so.0 libdbus-glib-1.so.2 libdbus-1.so.3" gtk3whitelist="libgtk-3.so.0 libgdk-3.so.0 libcairo-gobject.so.2 libpangocairo-1.0.so.0 libfribidi.so.0 libatk-1.0.so.0 libcairo.so.2 libgio-2.0.so.0 libpangoft2-1.0.so.0 libpango-1.0.so.0 libfontconfig.so.1 libfreetype.so.6 libgdk_pixbuf-2.0.so.0 libgobject-2.0.so.0 libglib-2.0.so.0 libgmodule-2.0.so.0 libgthread-2.0.so.0 libdbus-glib-1.so.2 libdbus-1.so.3" qt5whitelist="libQt5Core.so.5 libQt5Gui.so.5 libQt5Network.so.5 libQt5Widgets.so.5 libQt5X11Extras.so.5 libcairo.so.2 libglib-2.0.so.0 libgobject-2.0.so.0 libxcb.so.1" kf5whitelist="libKF5ConfigCore.so.5 libKF5CoreAddons.so.5 libKF5I18n.so.5 libKF5KIOCore.so.5 libKF5KIOFileWidgets.so.5 libKF5KIOWidgets.so.5 libKF5WindowSystem.so.5" @@ -129,10 +128,7 @@ local file="$1" whitelist="${whitelist} ${qt5whitelist} ${kf5whitelist}" fi ;; - */libvclplug_gtklo.so|*/libqstart_gtklo.so|*/updater) - whitelist="${whitelist} ${x11whitelist} ${gtk2whitelist}" - ;; - */libvclplug_gtk3lo.so) + */libvclplug_gtk3lo.so|*/updater) whitelist="${whitelist} ${x11whitelist} ${gtk3whitelist}" ;; */libvclplug_qt5lo.so) diff --git a/bin/distro-install-file-lists b/bin/distro-install-file-lists index 4cbe0be407ac..ef016e3df6cc 100755 --- a/bin/distro-install-file-lists +++ b/bin/distro-install-file-lists @@ -324,9 +324,6 @@ if test "z$OOO_VENDOR" != "zDebian" ; then mv_file_between_flists core_list.txt common_list.txt "$INSTALLDIR/$f" done - # Ship ooqstart for gnome in gnome package - mv_file_between_flists gnome_list.txt core_list.txt "$INSTALLDIR/program/libqstart_gtk680.*" - # themes are included in other packages # don't use remove_file as we don't want them removed from the buildroot. mv_file_between_flists /dev/null common_list.txt $INSTALLDIR/share/config/images_crystal.zip diff --git a/bin/moveglobalheaders.sh b/bin/moveglobalheaders.sh index 6c8cff729505..ca202832bd6a 100755 --- a/bin/moveglobalheaders.sh +++ b/bin/moveglobalheaders.sh @@ -36,8 +36,7 @@ done # we like to be special ... sed -ie 's/\/svtools\/inc\/svtools/\/include\/svtools\//' svtools/Library_svt.mk sed -ie 's/\/sfx2\/inc\/sfx2/\/include\/sfx2\//' sfx2/Library_sfx.mk -sed -ie 's/\/sfx2\/inc\/sfx2/\/include\/sfx2\//' sfx2/Library_qstart_gtk.mk -git add svtools/Library_svt.mk sfx2/Library_sfx.mk sfx2/Library_qstart_gtk.mk +git add svtools/Library_svt.mk sfx2/Library_sfx.mk # urgh sed -ie 's/\.\.\/svx\//svx\//' svx/source/svdraw/svdoashp.cxx diff --git a/config_host.mk.in b/config_host.mk.in index 122c9de745dd..29b85688b83f 100644 --- a/config_host.mk.in +++ b/config_host.mk.in @@ -142,8 +142,6 @@ export ENABLE_GIO=@ENABLE_GIO@ export ENABLE_GPGMEPP=@ENABLE_GPGMEPP@ export ENABLE_GSTREAMER_1_0=@ENABLE_GSTREAMER_1_0@ export ENABLE_GTK3=@ENABLE_GTK3@ -export ENABLE_GTK=@ENABLE_GTK@ -export ENABLE_GTK_PRINT=@ENABLE_GTK_PRINT@ export DISABLE_GUI=@DISABLE_GUI@ export ENABLE_HTMLHELP=@ENABLE_HTMLHELP@ export ENABLE_IOS_LIBREOFFICELIGHT_APP=@ENABLE_IOS_LIBREOFFICELIGHT_APP@ @@ -236,13 +234,8 @@ export GSSAPI_LIBS=@GSSAPI_LIBS@ export GSTREAMER_1_0_CFLAGS=$(gb_SPACE)@GSTREAMER_1_0_CFLAGS@ export GSTREAMER_1_0_LIBS=$(gb_SPACE)@GSTREAMER_1_0_LIBS@ export GTHREAD_CFLAGS=$(gb_SPACE)@GTHREAD_CFLAGS@ -export GTHREAD_LIBS=$(gb_SPACE)@GTHREAD_LIBS@ export GTK3_CFLAGS=$(gb_SPACE)@GTK3_CFLAGS@ export GTK3_LIBS=$(gb_SPACE)@GTK3_LIBS@ -export GTK_CFLAGS=$(gb_SPACE)@GTK_CFLAGS@ -export GTK_LIBS=$(gb_SPACE)@GTK_LIBS@ -export GTK_PRINT_CFLAGS=$(gb_SPACE)@GTK_PRINT_CFLAGS@ -export GTK_PRINT_LIBS=$(gb_SPACE)@GTK_PRINT_LIBS@ export USING_X11=@USING_X11@ export HAMCREST_JAR=@HAMCREST_JAR@ export HAVE_BROKEN_GCC_WMAYBE_UNINITIALIZED=@HAVE_BROKEN_GCC_WMAYBE_UNINITIALIZED@ diff --git a/config_host/config_vclplug.h.in b/config_host/config_vclplug.h.in index 694334dd4bf3..8ff5a9ce527f 100644 --- a/config_host/config_vclplug.h.in +++ b/config_host/config_vclplug.h.in @@ -7,7 +7,6 @@ Settings about which desktops have support enabled. #ifndef CONFIG_VCLPLUG_H #define CONFIG_VCLPLUG_H -#define ENABLE_GTK 0 #define ENABLE_GTK3 0 #define ENABLE_GTK3_KDE5 0 #define ENABLE_KF5 0 diff --git a/configure.ac b/configure.ac index cf0f6e501611..ce79ad5395af 100644 --- a/configure.ac +++ b/configure.ac @@ -574,7 +574,6 @@ SDKDIRNAME=sdk case "$host_os" in solaris*) - test_gtk=yes build_gstreamer_1_0=yes test_freetype=yes _os=SunOS @@ -600,7 +599,6 @@ solaris*) ;; linux-gnu*|k*bsd*-gnu*) - test_gtk=yes build_gstreamer_1_0=yes test_kf5=yes test_gtk3_kde5=yes @@ -649,7 +647,6 @@ cygwin*|interix*) ;; darwin*) # macOS or iOS - test_gtk=yes test_randr=no test_xrender=no test_freetype=no @@ -662,7 +659,6 @@ darwin*) # macOS or iOS if test "$host_cpu" = "arm64" -o "$enable_ios_simulator" = "yes"; then build_for_ios=YES _os=iOS - test_gtk=no test_cups=no enable_mpl_subset=yes enable_lotuswordpro=no @@ -694,7 +690,6 @@ darwin*) # macOS or iOS ;; freebsd*) - test_gtk=yes build_gstreamer_1_0=yes test_kf5=yes test_gtk3_kde5=yes @@ -722,7 +717,6 @@ freebsd*) ;; *netbsd*) - test_gtk=yes build_gstreamer_1_0=yes test_kf5=yes test_gtk3_kde5=yes @@ -739,7 +733,6 @@ aix*) ;; openbsd*) - test_gtk=yes test_freetype=yes PTHREAD_CFLAGS="-D_THREAD_SAFE" PTHREAD_LIBS="-pthread" @@ -747,7 +740,6 @@ openbsd*) ;; dragonfly*) - test_gtk=yes build_gstreamer_1_0=yes test_kf5=yes test_gtk3_kde5=yes @@ -770,7 +762,6 @@ linux-android*) test_dbus=no test_fontconfig=no test_freetype=no - test_gtk=no test_kf5=no test_qt5=no test_gtk3_kde5=no @@ -1204,11 +1195,6 @@ AC_ARG_ENABLE(python, 'fully-internal' even forces the internal version for uses of Python during the build.])) -libo_FUZZ_ARG_ENABLE(gtk, - AS_HELP_STRING([--disable-gtk], - [Determines whether to use Gtk+ vclplug on platforms where Gtk+ is available.]), -,test "${enable_gtk+set}" = set || enable_gtk=yes) - libo_FUZZ_ARG_ENABLE(gtk3, AS_HELP_STRING([--disable-gtk3], [Determines whether to use Gtk+ 3.0 vclplug on platforms where Gtk+ 3.0 is available.]), @@ -1652,12 +1638,12 @@ AC_ARG_WITH(system-jars, AC_ARG_WITH(system-cairo, AS_HELP_STRING([--with-system-cairo], [Use cairo libraries already on system. Happens automatically for - (implicit) --enable-gtk and for --enable-gtk3.])) + (implicit) --enable-gtk3.])) AC_ARG_WITH(system-epoxy, AS_HELP_STRING([--with-system-epoxy], [Use epoxy libraries already on system. Happens automatically for - --enable-gtk3.]),, + (implicit) --enable-gtk3.]),, [with_system_epoxy="$with_system_libs"]) AC_ARG_WITH(myspell-dicts, @@ -4716,7 +4702,6 @@ if test "$cross_compiling" = "yes"; then ./configure \ --disable-cups \ --disable-gstreamer-1-0 \ - --disable-gtk \ --disable-gtk3 \ --disable-pdfimport \ --disable-postgresql-sdbc \ @@ -4849,7 +4834,6 @@ if test "$USING_X11" != TRUE; then test_xrender=no test_cups=no test_dbus=no - test_gtk=no build_gstreamer_1_0=no test_kf5=no test_qt5=no @@ -10328,7 +10312,6 @@ dnl Test which vclplugs have to be built. dnl =================================================================== R="" if test "$USING_X11" != TRUE; then - enable_gtk=no enable_gtk3=no fi GTK3_CFLAGS="" @@ -10369,18 +10352,6 @@ if test "$enable_introspection" = yes; then fi fi -ENABLE_GTK="" -if test "x$enable_gtk" = "xyes"; then - if test "$with_system_cairo" = no; then - AC_MSG_ERROR([System cairo required for gtk support, do not use --without-system-cairo or use --disable-gtk]) - fi - : ${with_system_cairo:=yes} - ENABLE_GTK="TRUE" - AC_DEFINE(ENABLE_GTK) - R="gtk $R" -fi -AC_SUBST(ENABLE_GTK) - ENABLE_QT5="" if test "x$enable_qt5" = "xyes"; then ENABLE_QT5="TRUE" @@ -10531,61 +10502,27 @@ AC_SUBST(ENABLE_SDREMOTE_BLUETOOTH) AC_SUBST(SYSTEM_BLUEZ) dnl =================================================================== -dnl Check whether the gtk 2.0 libraries are available. -dnl =================================================================== - -GTK_CFLAGS="" -GTK_LIBS="" -if test "$test_gtk" = "yes"; then - - if test "$ENABLE_GTK" = "TRUE"; then - PKG_CHECK_MODULES(GTK, gtk+-2.0 >= 2.18.0 ,,AC_MSG_ERROR([requirements to build the gtk-plugin not met (gtk+-2.0 >= 2.18.0). Use --disable-gtk or install the missing packages])) - PKG_CHECK_MODULES(GTK, gdk-pixbuf-2.0 >= 2.2 ,,AC_MSG_ERROR([requirements to build the gtk-plugin not met (gdk-pixbuf-2.0 >= 2.2). Use --disable-gtk or install the missing packages])) - GTK_CFLAGS=$(printf '%s' "$GTK_CFLAGS" | sed -e "s/-I/${ISYSTEM?}/g") - FilterLibs "${GTK_LIBS}" - GTK_LIBS="${filteredlibs}" - PKG_CHECK_MODULES(GTHREAD, gthread-2.0,,AC_MSG_ERROR([requirements to build the gtk-plugin not met (gthread-2.0). Use --disable-gtk or install the missing packages])) - BUILD_TYPE="$BUILD_TYPE GTK" - GTHREAD_CFLAGS=$(printf '%s' "$GTK_CFLAGS" | sed -e "s/-I/${ISYSTEM?}/g") - FilterLibs "${GTHREAD_LIBS}" - GTHREAD_LIBS="${filteredlibs}" - - AC_MSG_CHECKING([whether to enable Gtk print dialog support]) - PKG_CHECK_MODULES([GTK_PRINT], [gtk+-unix-print-2.0 >= 2.10.0], - [ENABLE_GTK_PRINT="TRUE"], - [ENABLE_GTK_PRINT=""]) - GTK_PRINT_CFLAGS=$(printf '%s' "$GTK_PRINT_CFLAGS" | sed -e "s/-I/${ISYSTEM?}/g") - FilterLibs "${GTK_PRINT_LIBS}" - GTK_PRINT_LIBS="${filteredlibs}" - fi - - if test "$ENABLE_GTK" = "TRUE" || test "$ENABLE_GTK3" = "TRUE"; then - AC_MSG_CHECKING([whether to enable GIO support]) - if test "$_os" != "WINNT" -a "$_os" != "Darwin" -a "$enable_gio" = "yes"; then - dnl Need at least 2.26 for the dbus support. - PKG_CHECK_MODULES([GIO], [gio-2.0 >= 2.26], - [ENABLE_GIO="TRUE"], [ENABLE_GIO=""]) - if test "$ENABLE_GIO" = "TRUE"; then - AC_DEFINE(ENABLE_GIO) - GIO_CFLAGS=$(printf '%s' "$GIO_CFLAGS" | sed -e "s/-I/${ISYSTEM?}/g") - FilterLibs "${GIO_LIBS}" - GIO_LIBS="${filteredlibs}" - fi - else - AC_MSG_RESULT([no]) +dnl Check whether to enable GIO support +dnl =================================================================== +if test "$ENABLE_GTK3" = "TRUE"; then + AC_MSG_CHECKING([whether to enable GIO support]) + if test "$_os" != "WINNT" -a "$_os" != "Darwin" -a "$enable_gio" = "yes"; then + dnl Need at least 2.26 for the dbus support. + PKG_CHECK_MODULES([GIO], [gio-2.0 >= 2.26], + [ENABLE_GIO="TRUE"], [ENABLE_GIO=""]) + if test "$ENABLE_GIO" = "TRUE"; then + AC_DEFINE(ENABLE_GIO) + GIO_CFLAGS=$(printf '%s' "$GIO_CFLAGS" | sed -e "s/-I/${ISYSTEM?}/g") + FilterLibs "${GIO_LIBS}" + GIO_LIBS="${filteredlibs}" fi + else + AC_MSG_RESULT([no]) fi fi AC_SUBST(ENABLE_GIO) AC_SUBST(GIO_CFLAGS) AC_SUBST(GIO_LIBS) -AC_SUBST(GTK_CFLAGS) -AC_SUBST(GTK_LIBS) -AC_SUBST(GTHREAD_CFLAGS) -AC_SUBST(GTHREAD_LIBS) -AC_SUBST([ENABLE_GTK_PRINT]) -AC_SUBST([GTK_PRINT_CFLAGS]) -AC_SUBST([GTK_PRINT_LIBS]) dnl =================================================================== diff --git a/cui/Library_cui.mk b/cui/Library_cui.mk index 8a2bf42d79c1..54e3733daef1 100644 --- a/cui/Library_cui.mk +++ b/cui/Library_cui.mk @@ -20,7 +20,6 @@ $(eval $(call gb_Library_set_include,cui,\ $(eval $(call gb_Library_set_precompiled_header,cui,cui/inc/pch/precompiled_cui)) $(eval $(call gb_Library_add_defs,cui,\ - $(if $(filter TRUE,$(ENABLE_GTK)),-DENABLE_GTK) \ -DCUI_DLLIMPLEMENTATION \ )) diff --git a/cui/source/options/optgdlg.cxx b/cui/source/options/optgdlg.cxx index bcf1d7a73fab..c0b840302864 100644 --- a/cui/source/options/optgdlg.cxx +++ b/cui/source/options/optgdlg.cxx @@ -18,6 +18,7 @@ */ #include <config_features.h> +#include <config_vclplug.h> #include <svl/zforlist.hxx> #include <svl/currencytable.hxx> #include <svtools/langhelp.hxx> @@ -257,7 +258,7 @@ OfaMiscTabPage::OfaMiscTabPage(weld::Container* pPage, weld::DialogController* p m_xFileDlgCB->set_sensitive(false); } -#if ! ENABLE_GTK +#if !ENABLE_GTK3 m_xPrintDlgFrame->hide(); #else if (!SvtMiscOptions().IsExperimentalMode()) @@ -269,7 +270,7 @@ OfaMiscTabPage::OfaMiscTabPage(weld::Container* pPage, weld::DialogController* p m_xQuickLaunchCB->show(); //Only available in Win or if building the gtk systray -#if !defined(_WIN32) && ! ENABLE_GTK +#if !defined(_WIN32) m_xQuickStarterFrame->hide(); #endif diff --git a/desktop/Pagein_common.mk b/desktop/Pagein_common.mk index ca5873db7903..c1661a39b641 100644 --- a/desktop/Pagein_common.mk +++ b/desktop/Pagein_common.mk @@ -28,7 +28,7 @@ $(eval $(call gb_Pagein_add_objects,common,\ ucb1 \ configmgr \ vclplug_gen \ - $(if $(findstring TRUE,$(ENABLE_GTK)),vclplug_gtk) \ + $(if $(findstring TRUE,$(ENABLE_GTK3)),vclplug_gtk3) \ basegfx \ sot \ xmlscript \ diff --git a/distro-configs/LibreOfficeFlatpak.conf b/distro-configs/LibreOfficeFlatpak.conf index 5bdba7501869..0d0f9ce5c881 100644 --- a/distro-configs/LibreOfficeFlatpak.conf +++ b/distro-configs/LibreOfficeFlatpak.conf @@ -1,4 +1,3 @@ ---disable-gtk --disable-odk --enable-release-build --with-ant-home=/run/build/libreoffice/ant diff --git a/distro-configs/LibreOfficeMacOSX.conf b/distro-configs/LibreOfficeMacOSX.conf index a4f913c7ec7e..fc7291ca7f9d 100644 --- a/distro-configs/LibreOfficeMacOSX.conf +++ b/distro-configs/LibreOfficeMacOSX.conf @@ -5,7 +5,6 @@ --enable-extension-integration --enable-online-update --without-system-postgresql ---disable-gtk --with-help=html --with-myspell-dicts --with-package-format=dmg diff --git a/distro-configs/LibreOfficeOnline.conf b/distro-configs/LibreOfficeOnline.conf index 75b885a4afb1..a007b85103c7 100644 --- a/distro-configs/LibreOfficeOnline.conf +++ b/distro-configs/LibreOfficeOnline.conf @@ -8,7 +8,6 @@ --disable-firebird-sdbc --disable-gio --disable-gstreamer-1-0 ---disable-gtk --disable-gtk3 --disable-gui --disable-qt5 diff --git a/distro-configs/LibreOfficeOssFuzz.conf b/distro-configs/LibreOfficeOssFuzz.conf index 1cca285ff058..ab9ec3b3b01e 100644 --- a/distro-configs/LibreOfficeOssFuzz.conf +++ b/distro-configs/LibreOfficeOssFuzz.conf @@ -4,7 +4,6 @@ --disable-runtime-optimizations --disable-database-connectivity --disable-gui ---disable-gtk --disable-gtk3 --disable-pdfium --disable-postgresql-sdbc diff --git a/onlineupdate/Executable_test_updater_dialog.mk b/onlineupdate/Executable_test_updater_dialog.mk index bd144c8bca18..a2988d0079d6 100644 --- a/onlineupdate/Executable_test_updater_dialog.mk +++ b/onlineupdate/Executable_test_updater_dialog.mk @@ -15,6 +15,7 @@ $(eval $(call gb_Executable_set_include,test_updater_dialog,\ -I$(SRCDIR)/onlineupdate/source/update/updater/xpcom/glue \ -I$(SRCDIR)/onlineupdate/source/update/updater \ $$(INCLUDE) \ + $(if $(filter-out WNT,$(OS)),$$(GTK3_CFLAGS) ) \ )) $(eval $(call gb_Executable_use_static_libraries,test_updater_dialog,\ @@ -48,15 +49,10 @@ $(eval $(call gb_Executable_add_defs,test_updater_dialog,\ $(eval $(call gb_Executable_use_externals,test_updater_dialog,\ nss3 \ - gtk \ )) $(eval $(call gb_Executable_add_libs,test_updater_dialog,\ - -lX11 \ - -lXext \ - -lXrender \ - -lSM \ - -lICE \ + $(GTK3_LIBS) \ )) endif diff --git a/onlineupdate/Executable_updater.mk b/onlineupdate/Executable_updater.mk index 7c24b7beb3bb..ab15a94e4c60 100644 --- a/onlineupdate/Executable_updater.mk +++ b/onlineupdate/Executable_updater.mk @@ -14,6 +14,7 @@ $(eval $(call gb_Executable_set_include,updater,\ -I$(SRCDIR)/onlineupdate/source/update/common \ -I$(SRCDIR)/onlineupdate/source/update/updater/xpcom/glue \ $$(INCLUDE) \ + $(if $(filter-out WNT,$(OS)),$$(GTK3_CFLAGS) ) \ )) $(eval $(call gb_Executable_use_custom_headers,updater,onlineupdate/generated)) @@ -61,16 +62,12 @@ $(eval $(call gb_Executable_add_defs,updater,\ $(eval $(call gb_Executable_use_externals,updater,\ nss3 \ - gtk \ )) $(eval $(call gb_Executable_add_libs,updater,\ - -lX11 \ - -lXext \ - -lXrender \ - -lSM \ - -lICE \ + $(GTK3_LIBS) \ )) + endif $(eval $(call gb_Executable_add_exception_objects,updater,\ diff --git a/onlineupdate/source/update/updater/progressui_gtk.cxx b/onlineupdate/source/update/updater/progressui_gtk.cxx index 47d27ea02c17..7c3bcfcd8b2d 100644 --- a/onlineupdate/source/update/updater/progressui_gtk.cxx +++ b/onlineupdate/source/update/updater/progressui_gtk.cxx @@ -14,6 +14,11 @@ #include <string.h> #include "progressui_gtk_icon.h" +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif + #define TIMER_INTERVAL 100 static float sProgressVal; // between 0 and 100 @@ -133,4 +138,9 @@ UpdateProgressUI(float progress) { sProgressVal = progress; // 32-bit writes are atomic } + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + #endif // defined(UNIX) || defined(MACOSX) diff --git a/scp2/InstallScript_setup_osl.mk b/scp2/InstallScript_setup_osl.mk index 0c3b97bef6d7..6f7b58204225 100644 --- a/scp2/InstallScript_setup_osl.mk +++ b/scp2/InstallScript_setup_osl.mk @@ -33,7 +33,7 @@ $(eval $(call gb_InstallScript_use_modules,setup_osl,\ $(if $(WITH_EXTENSION_INTEGRATION),\ scp2/extensions \ ) \ - $(if $(filter TRUE,$(ENABLE_EVOAB2) $(ENABLE_GIO) $(ENABLE_GTK) $(ENABLE_GTK3)),\ + $(if $(filter TRUE,$(ENABLE_EVOAB2) $(ENABLE_GIO) $(ENABLE_GTK3)),\ scp2/gnome \ ) \ $(if $(filter TRUE,$(ENABLE_QT5) $(ENABLE_KF5) $(ENABLE_GTK3_KDE5)),\ diff --git a/scp2/Module_scp2.mk b/scp2/Module_scp2.mk index aa06d6301f85..25ae8167df56 100644 --- a/scp2/Module_scp2.mk +++ b/scp2/Module_scp2.mk @@ -37,7 +37,7 @@ $(eval $(call gb_Module_add_targets,scp2,\ InstallModule_windows \ InstallModule_winexplorerext \ ) \ - $(if $(filter TRUE,$(ENABLE_EVOAB2) $(ENABLE_GIO) $(ENABLE_GTK) $(ENABLE_GTK3)),\ + $(if $(filter TRUE,$(ENABLE_EVOAB2) $(ENABLE_GIO) $(ENABLE_GTK3)),\ InstallModule_gnome \ ) \ $(if $(filter TRUE,$(ENABLE_QT5) $(ENABLE_KF5) $(ENABLE_GTK3_KDE5)),\ diff --git a/sd/CppunitTest_sd_uimpress.mk b/sd/CppunitTest_sd_uimpress.mk index 4a36cc687062..94229cc2c8e3 100644 --- a/sd/CppunitTest_sd_uimpress.mk +++ b/sd/CppunitTest_sd_uimpress.mk @@ -71,7 +71,6 @@ endif $(eval $(call gb_CppunitTest_use_externals,sd_uimpress,\ boost_headers \ - gtk \ dbus \ $(if $(ENABLE_AVAHI), \ avahi \ diff --git a/solenv/clang-format/blacklist b/solenv/clang-format/blacklist index c89b6861b7d9..d694f0b3d02b 100644 --- a/solenv/clang-format/blacklist +++ b/solenv/clang-format/blacklist @@ -18113,51 +18113,13 @@ vcl/unx/generic/window/salframe.cxx vcl/unx/generic/window/salobj.cxx vcl/unx/generic/window/screensaverinhibitor.cxx vcl/unx/glxtest.cxx -vcl/unx/gtk/a11y/atkaction.cxx -vcl/unx/gtk/a11y/atkbridge.cxx -vcl/unx/gtk/a11y/atkcomponent.cxx -vcl/unx/gtk/a11y/atkeditabletext.cxx -vcl/unx/gtk/a11y/atkfactory.cxx -vcl/unx/gtk/a11y/atkfactory.hxx -vcl/unx/gtk/a11y/atkhypertext.cxx -vcl/unx/gtk/a11y/atkimage.cxx -vcl/unx/gtk/a11y/atklistener.cxx -vcl/unx/gtk/a11y/atklistener.hxx -vcl/unx/gtk/a11y/atkregistry.cxx -vcl/unx/gtk/a11y/atkregistry.hxx -vcl/unx/gtk/a11y/atkselection.cxx -vcl/unx/gtk/a11y/atktable.cxx -vcl/unx/gtk/a11y/atktext.cxx -vcl/unx/gtk/a11y/atktextattributes.cxx -vcl/unx/gtk/a11y/atktextattributes.hxx -vcl/unx/gtk/a11y/atkutil.cxx -vcl/unx/gtk/a11y/atkutil.hxx -vcl/unx/gtk/a11y/atkvalue.cxx -vcl/unx/gtk/a11y/atkwindow.cxx -vcl/unx/gtk/a11y/atkwindow.hxx -vcl/unx/gtk/a11y/atkwrapper.cxx -vcl/unx/gtk/a11y/atkwrapper.hxx -vcl/unx/gtk/fpicker/SalGtkFilePicker.cxx -vcl/unx/gtk/fpicker/SalGtkFilePicker.hxx -vcl/unx/gtk/fpicker/SalGtkFolderPicker.cxx -vcl/unx/gtk/fpicker/SalGtkFolderPicker.hxx -vcl/unx/gtk/fpicker/SalGtkPicker.cxx -vcl/unx/gtk/fpicker/SalGtkPicker.hxx -vcl/unx/gtk/fpicker/eventnotification.hxx -vcl/unx/gtk/fpicker/resourceprovider.cxx -vcl/unx/gtk/gloactiongroup.cxx -vcl/unx/gtk/glomenu.cxx -vcl/unx/gtk/gtkdata.cxx -vcl/unx/gtk/gtkinst.cxx -vcl/unx/gtk/gtkobject.cxx -vcl/unx/gtk/gtkprintwrapper.cxx -vcl/unx/gtk/gtksalframe.cxx -vcl/unx/gtk/gtksalmenu.cxx -vcl/unx/gtk/gtksys.cxx -vcl/unx/gtk/hudawareness.cxx -vcl/unx/gtk/salnativewidgets-gtk.cxx -vcl/unx/gtk/salprn-gtk.cxx -vcl/unx/gtk/xid_fullscreen_on_all_monitors.c +vcl/unx/gtk3/a11y/atkfactory.hxx +vcl/unx/gtk3/a11y/atklistener.hxx +vcl/unx/gtk3/a11y/atkregistry.hxx +vcl/unx/gtk3/a11y/atktextattributes.hxx +vcl/unx/gtk3/a11y/atkutil.hxx +vcl/unx/gtk3/a11y/atkwindow.hxx +vcl/unx/gtk3/a11y/atkwrapper.hxx vcl/unx/gtk3/a11y/gtk3atkaction.cxx vcl/unx/gtk3/a11y/gtk3atkbridge.cxx vcl/unx/gtk3/a11y/gtk3atkcomponent.cxx @@ -18175,9 +18137,16 @@ vcl/unx/gtk3/a11y/gtk3atkutil.cxx vcl/unx/gtk3/a11y/gtk3atkvalue.cxx vcl/unx/gtk3/a11y/gtk3atkwindow.cxx vcl/unx/gtk3/a11y/gtk3atkwrapper.cxx +vcl/unx/gtk3/fpicker/SalGtkFilePicker.cxx +vcl/unx/gtk3/fpicker/SalGtkFilePicker.hxx +vcl/unx/gtk3/fpicker/SalGtkFolderPicker.cxx +vcl/unx/gtk3/fpicker/SalGtkFolderPicker.hxx +vcl/unx/gtk3/fpicker/SalGtkPicker.cxx +vcl/unx/gtk3/fpicker/SalGtkPicker.hxx +vcl/unx/gtk3/fpicker/eventnotification.hxx +vcl/unx/gtk3/fpicker/resourceprovider.cxx vcl/unx/gtk3/cairo_gtk3_cairo.cxx vcl/unx/gtk3/cairo_gtk3_cairo.hxx -vcl/unx/gtk3/gtk3fpicker.cxx vcl/unx/gtk3/gtk3gloactiongroup.cxx vcl/unx/gtk3/gtk3glomenu.cxx vcl/unx/gtk3/gtk3gtkdata.cxx diff --git a/solenv/gbuild/CppunitTest.mk b/solenv/gbuild/CppunitTest.mk index 7c5c251eff46..0d40bd6cdb5d 100644 --- a/solenv/gbuild/CppunitTest.mk +++ b/solenv/gbuild/CppunitTest.mk @@ -224,7 +224,6 @@ ifeq ($(USING_X11),TRUE) $(call gb_CppunitTest_get_target,$(1)) : $(call gb_Library_get_target,desktop_detector) $(call gb_CppunitTest_get_target,$(1)) : $(if $(filter $(2),$(true)),, \ $(call gb_Library_get_target,vclplug_gen) \ - $(if $(ENABLE_GTK),$(call gb_Library_get_target,vclplug_gtk)) \ $(if $(ENABLE_GTK3),$(call gb_Library_get_target,vclplug_gtk3)) \ $(if $(ENABLE_QT5),$(call gb_Library_get_target,vclplug_qt5)) \ ) diff --git a/vcl/Executable_xid_fullscreen_on_all_monitors.mk b/vcl/Executable_xid_fullscreen_on_all_monitors.mk deleted file mode 100644 index 296436abd106..000000000000 --- a/vcl/Executable_xid_fullscreen_on_all_monitors.mk +++ /dev/null @@ -1,22 +0,0 @@ -# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- -# -# This file is part of the LibreOffice project. -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -# - -$(eval $(call gb_Executable_Executable,xid-fullscreen-on-all-monitors)) - -ifeq ($(filter ANDROID WNT DRAGONFLY FREEBSD NETBSD OPENBSD MACOSX,$(OS)),) -$(eval $(call gb_Executable_add_libs,xid-fullscreen-on-all-monitors,\ - -ldl \ -)) -endif - -$(eval $(call gb_Executable_add_cobjects,xid-fullscreen-on-all-monitors,\ - vcl/unx/gtk/xid_fullscreen_on_all_monitors \ -)) - -# vim: set noet sw=4 ts=4: diff --git a/vcl/Library_vclplug_gtk.mk b/vcl/Library_vclplug_gtk.mk deleted file mode 100644 index 360eabf46020..000000000000 --- a/vcl/Library_vclplug_gtk.mk +++ /dev/null @@ -1,132 +0,0 @@ -# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- -# -# This file is part of the LibreOffice project. -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -# -# This file incorporates work covered by the following license notice: -# -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed -# with this work for additional information regarding copyright -# ownership. The ASF licenses this file to you under the Apache -# License, Version 2.0 (the "License"); you may not use this file -# except in compliance with the License. You may obtain a copy of -# the License at http://www.apache.org/licenses/LICENSE-2.0 . -# - -$(eval $(call gb_Library_Library,vclplug_gtk)) - -$(eval $(call gb_Library_set_include,vclplug_gtk,\ - $$(INCLUDE) \ - -I$(SRCDIR)/vcl/inc \ - -I$(SRCDIR)/vcl/unx \ - -I$(SRCDIR)/vcl/unx/gtk \ -)) - -$(eval $(call gb_Library_add_defs,vclplug_gtk,\ - -DVCLPLUG_GTK_IMPLEMENTATION \ -)) - -$(eval $(call gb_Library_use_custom_headers,vclplug_gtk,\ - officecfg/registry \ -)) - -$(eval $(call gb_Library_use_sdk_api,vclplug_gtk)) - -$(eval $(call gb_Library_use_libraries,vclplug_gtk,\ - vclplug_gen \ - vcl \ - tl \ - utl \ - sot \ - ucbhelper \ - basegfx \ - comphelper \ - cppuhelper \ - i18nlangtag \ - i18nutil \ - $(if $(ENABLE_JAVA), \ - jvmaccess) \ - cppu \ - sal \ -)) - -$(eval $(call gb_Library_use_externals,vclplug_gtk,\ - boost_headers \ - cairo \ - dbus \ - epoxy \ - gio \ - graphite \ - gthread \ - gtk \ - harfbuzz \ - icuuc \ -)) - -$(eval $(call gb_Library_add_libs,vclplug_gtk,\ - -lX11 \ - -lXext \ - -lSM \ - -lICE \ -)) - -$(eval $(call gb_Library_add_exception_objects,vclplug_gtk,\ - vcl/unx/gtk/a11y/atkaction \ - vcl/unx/gtk/a11y/atkbridge \ - vcl/unx/gtk/a11y/atkcomponent \ - vcl/unx/gtk/a11y/atkeditabletext \ - vcl/unx/gtk/a11y/atkfactory \ - vcl/unx/gtk/a11y/atkhypertext \ - vcl/unx/gtk/a11y/atkimage \ - vcl/unx/gtk/a11y/atklistener \ - vcl/unx/gtk/a11y/atkregistry \ - vcl/unx/gtk/a11y/atkselection \ - vcl/unx/gtk/a11y/atktable \ - vcl/unx/gtk/a11y/atktextattributes \ - vcl/unx/gtk/a11y/atktext \ - vcl/unx/gtk/a11y/atkutil \ - vcl/unx/gtk/a11y/atkvalue \ - vcl/unx/gtk/a11y/atkwindow \ - vcl/unx/gtk/a11y/atkwrapper \ - vcl/unx/gtk/gtkdata \ - vcl/unx/gtk/gtkinst \ - vcl/unx/gtk/gtksys \ - vcl/unx/gtk/salnativewidgets-gtk \ - vcl/unx/gtk/gtksalframe \ - vcl/unx/gtk/gtkobject \ - vcl/unx/gtk/fpicker/resourceprovider \ - vcl/unx/gtk/fpicker/SalGtkPicker \ - vcl/unx/gtk/fpicker/SalGtkFilePicker \ - vcl/unx/gtk/fpicker/SalGtkFolderPicker \ -)) - -ifneq ($(ENABLE_DBUS),) -ifneq ($(ENABLE_GIO),) -$(eval $(call gb_Library_add_exception_objects,vclplug_gtk,\ - vcl/unx/gtk/gloactiongroup \ - vcl/unx/gtk/gtksalmenu \ - vcl/unx/gtk/glomenu \ - vcl/unx/gtk/hudawareness \ -)) -endif -endif - -ifeq ($(ENABLE_GTK_PRINT),TRUE) -$(eval $(call gb_Library_add_exception_objects,vclplug_gtk,\ - vcl/unx/gtk/gtkprintwrapper \ - vcl/unx/gtk/salprn-gtk \ -)) -endif - -ifeq ($(OS),LINUX) -$(eval $(call gb_Library_add_libs,vclplug_gtk,\ - -lm \ - -ldl \ -)) -endif - -# vim: set noet sw=4 ts=4: diff --git a/vcl/Library_vclplug_gtk3.mk b/vcl/Library_vclplug_gtk3.mk index c0ad6cd21e52..9f6504c38f56 100644 --- a/vcl/Library_vclplug_gtk3.mk +++ b/vcl/Library_vclplug_gtk3.mk @@ -46,7 +46,6 @@ $(eval $(call gb_Library_use_sdk_api,vclplug_gtk3)) $(eval $(call gb_Library_add_libs,vclplug_gtk3,\ $(GTK3_LIBS) \ - $(GTHREAD_LIBS) \ -lX11 \ -lXext \ -lSM \ @@ -97,10 +96,13 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_gtk3,\ vcl/unx/gtk3/a11y/gtk3atkvalue \ vcl/unx/gtk3/a11y/gtk3atkwindow \ vcl/unx/gtk3/a11y/gtk3atkwrapper \ + vcl/unx/gtk3/fpicker/resourceprovider \ + vcl/unx/gtk3/fpicker/SalGtkFilePicker \ + vcl/unx/gtk3/fpicker/SalGtkFolderPicker \ + vcl/unx/gtk3/fpicker/SalGtkPicker \ vcl/unx/gtk3/gtk3gtkdata \ vcl/unx/gtk3/gtk3gtkinst \ vcl/unx/gtk3/gtk3gtksys \ - vcl/unx/gtk3/gtk3fpicker \ vcl/unx/gtk3/cairo_gtk3_cairo \ vcl/unx/gtk3/gtk3gtkprintwrapper \ vcl/unx/gtk3/gtk3salnativewidgets-gtk \ diff --git a/vcl/Library_vclplug_gtk3_kde5.mk b/vcl/Library_vclplug_gtk3_kde5.mk index d67c53e2a6f5..231726449c4e 100644 --- a/vcl/Library_vclplug_gtk3_kde5.mk +++ b/vcl/Library_vclplug_gtk3_kde5.mk @@ -51,7 +51,6 @@ $(eval $(call gb_Library_use_sdk_api,vclplug_gtk3_kde5)) $(eval $(call gb_Library_add_libs,vclplug_gtk3_kde5,\ $(GTK3_LIBS) \ - $(GTHREAD_LIBS) \ -lX11 \ -lXext \ -lSM \ diff --git a/vcl/Module_vcl.mk b/vcl/Module_vcl.mk index 54e3fbd6b07f..859702ca4032 100644 --- a/vcl/Module_vcl.mk +++ b/vcl/Module_vcl.mk @@ -66,12 +66,6 @@ $(eval $(call gb_Module_add_targets,vcl,\ Package_fontunxpsprint \ )) -ifneq ($(ENABLE_GTK),) -$(eval $(call gb_Module_add_targets,vcl,\ - Executable_xid_fullscreen_on_all_monitors \ - Library_vclplug_gtk \ -)) -endif ifneq ($(ENABLE_GTK3),) $(eval $(call gb_Module_add_targets,vcl,\ Library_vclplug_gtk3 \ diff --git a/vcl/inc/unx/gtk/gtkdata.hxx b/vcl/inc/unx/gtk/gtkdata.hxx index f1750b7dc3a6..84e2d19f6c94 100644 --- a/vcl/inc/unx/gtk/gtkdata.hxx +++ b/vcl/inc/unx/gtk/gtkdata.hxx @@ -42,44 +42,22 @@ class DocumentFocusListener; inline GdkWindow * widget_get_window(GtkWidget *widget) { -#if GTK_CHECK_VERSION(3,0,0) return gtk_widget_get_window(widget); -#else - return widget->window; -#endif } inline ::Window widget_get_xid(GtkWidget *widget) { -#if GTK_CHECK_VERSION(3,0,0) return GDK_WINDOW_XID(gtk_widget_get_window(widget)); -#else - return GDK_WINDOW_XWINDOW(widget->window); -#endif } inline void widget_set_can_focus(GtkWidget *widget, gboolean can_focus) { -#if GTK_CHECK_VERSION(3,0,0) return gtk_widget_set_can_focus(widget, can_focus); -#else - if (can_focus) - GTK_WIDGET_SET_FLAGS( widget, GTK_CAN_FOCUS ); - else - GTK_WIDGET_UNSET_FLAGS( widget, GTK_CAN_FOCUS ); -#endif } inline void widget_set_can_default(GtkWidget *widget, gboolean can_default) { -#if GTK_CHECK_VERSION(3,0,0) return gtk_widget_set_can_default(widget, can_default); -#else - if (can_default) - GTK_WIDGET_SET_FLAGS( widget, GTK_CAN_DEFAULT ); - else - GTK_WIDGET_UNSET_FLAGS( widget, GTK_CAN_DEFAULT ); -#endif } class GtkSalTimer final : public SalTimer @@ -132,11 +110,7 @@ public: class GtkSalFrame; -#if GTK_CHECK_VERSION(3,0,0) class GtkSalDisplay : public SalGenericDisplay -#else -class GtkSalDisplay : public SalDisplay -#endif { GtkSalSystem* m_pSys; GdkDisplay* const m_pGdkDisplay; @@ -161,20 +135,11 @@ public: virtual void deregisterFrame( SalFrame* pFrame ) override; GdkCursor *getCursor( PointerStyle ePointerStyle ); -#if GTK_CHECK_VERSION(3,0,0) virtual int CaptureMouse( SalFrame* pFrame ); -#else - virtual int CaptureMouse( SalFrame* pFrame ) override; -#endif SalX11Screen GetDefaultXScreen() { return m_pSys->GetDisplayDefaultXScreen(); } Size GetScreenSize( int nDisplayScreen ); int GetXScreenCount() { return m_pSys->GetDisplayXScreenCount(); } -#if GTK_CHECK_VERSION(3,0,0) -// int GetScreenCount() { return m_pSys->GetDisplayScreenCount(); } -#else - virtual ScreenData *initScreen( SalX11Screen nXScreen ) const override; -#endif GdkFilterReturn filterGdkEvent( GdkXEvent* sys_event ); void startupNotificationCompleted() { m_bStartupCompleted = true; } @@ -185,12 +150,7 @@ public: virtual void TriggerUserEventProcessing() override; virtual void TriggerAllUserEventsProcessed() override; -#if !GTK_CHECK_VERSION(3,0,0) - virtual bool Dispatch( XEvent *pEvent ) override; -#endif -#if GTK_CHECK_VERSION(3,0,0) void RefreshMenusUnity(); -#endif }; inline GtkSalData* GetGtkSalData() diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx index 084339f96d70..f9a41c6c3cf6 100644 --- a/vcl/inc/unx/gtk/gtkframe.hxx +++ b/vcl/inc/unx/gtk/gtkframe.hxx @@ -24,9 +24,7 @@ #include <gdk/gdk.h> #include <gdk/gdkx.h> #include <gtk/gtk.h> -#if GTK_CHECK_VERSION(3,0,0) -# include <gtk/gtkx.h> -#endif +#include <gtk/gtkx.h> #include <gdk/gdkkeysyms.h> #include <salframe.hxx> @@ -54,7 +52,6 @@ class GtkSalGraphics; class GtkSalDisplay; -#if GTK_CHECK_VERSION(3,0,0) typedef sal_uIntPtr GdkNativeWindow; #define GDK_WINDOW_XWINDOW(o) GDK_WINDOW_XID(o) #define gdk_set_sm_client_id(i) gdk_x11_set_sm_client_id(i) @@ -62,11 +59,6 @@ typedef sal_uIntPtr GdkNativeWindow; class GtkDropTarget; class GtkDragSource; class GtkDnDTransferable; -#endif - -#if !(GLIB_MAJOR_VERSION > 2 || GLIB_MINOR_VERSION >= 26) - typedef void GDBusConnection; -#endif class GtkSalMenu; @@ -172,10 +164,8 @@ class GtkSalFrame : public SalFrame SalX11Screen m_nXScreen; GtkWidget* m_pWindow; -#if GTK_CHECK_VERSION(3,0,0) GtkHeaderBar* m_pHeaderBar; GtkGrid* m_pTopLevelGrid; -#endif GtkEventBox* m_pEventBox; GtkFixed* m_pFixedContainer; GdkWindow* m_pForeignParent; @@ -208,7 +198,6 @@ class GtkSalFrame : public SalFrame Size m_aMinSize; tools::Rectangle m_aRestorePosSize; -#if GTK_CHECK_VERSION(3,0,0) OUString m_aTooltip; tools::Rectangle m_aHelpArea; tools::Rectangle m_aFloatRect; @@ -220,10 +209,6 @@ class GtkSalFrame : public SalFrame GtkDropTarget* m_pDropTarget; GtkDragSource* m_pDragSource; bool m_bGeometryIsProvisional; -#else - GdkRegion* m_pRegion; - bool m_bSetFocusOnMap; -#endif GtkSalMenu* m_pSalMenu; @@ -242,12 +227,7 @@ class GtkSalFrame : public SalFrame // signals static gboolean signalButton( GtkWidget*, GdkEventButton*, gpointer ); -#if GTK_CHECK_VERSION(3,0,0) static void signalStyleUpdated(GtkWidget*, gpointer); -#else - static void signalStyleSet(GtkWidget*, GtkStyle* pPrevious, gpointer); -#endif -#if GTK_CHECK_VERSION(3,0,0) static gboolean signalDraw( GtkWidget*, cairo_t *cr, gpointer ); static void signalRealize(GtkWidget*, gpointer frame); static void sizeAllocated(GtkWidget*, GdkRectangle *pAllocation, gpointer frame); @@ -270,11 +250,6 @@ class GtkSalFrame : public SalFrame static void gestureSwipe(GtkGestureSwipe* gesture, gdouble velocity_x, gdouble velocity_y, gpointer frame); static void gestureLongPress(GtkGestureLongPress* gesture, gdouble x, gdouble y, gpointer frame); -#else - static gboolean signalExpose( GtkWidget*, GdkEventExpose*, gpointer ); - void askForXEmbedFocus( sal_Int32 nTimecode ); - void grabKeyboard(bool bGrab); -#endif static gboolean signalFocus( GtkWidget*, GdkEventFocus*, gpointer ); static gboolean signalMap( GtkWidget*, GdkEvent*, gpointer ); static gboolean signalUnmap( GtkWidget*, GdkEvent*, gpointer ); @@ -345,7 +320,6 @@ class GtkSalFrame : public SalFrame void SetScreen( unsigned int nNewScreen, SetType eType, tools::Rectangle const *pSize = nullptr ); public: -#if GTK_CHECK_VERSION(3,0,0) cairo_surface_t* m_pSurface; basegfx::B2IVector m_aFrameSize; DamageHandler m_aDamageHandler; @@ -353,7 +327,6 @@ public: Idle m_aSmoothScrollIdle; int m_nGrabLevel; bool m_bSalObjectSetPosSize; -#endif GtkSalFrame( SalFrame* pParent, SalFrameStyleFlags nStyle ); GtkSalFrame( SystemParentData* pSysData ); @@ -374,9 +347,7 @@ public: GtkFixed* getFixedContainer() const { return m_pFixedContainer; } GtkEventBox* getEventBox() const { return m_pEventBox; } GtkWidget* getMouseEventWidget() const; -#if GTK_CHECK_VERSION(3,0,0) GtkGrid* getTopLevelGridWidget() const { return m_pTopLevelGrid; } -#endif GdkWindow* getForeignParent() const { return m_pForeignParent; } GdkNativeWindow getForeignParentWindow() const { return m_aForeignParentWindow; } GdkWindow* getForeignTopLevel() const { return m_pForeignTopLevel; } @@ -385,8 +356,6 @@ public: int GetDisplayScreen() const { return maGeometry.nDisplayScreenNumber; } void updateScreenNumber(); -#if GTK_CHECK_VERSION(3,0,0) - // only for gtk3 ... cairo_t* getCairoContext() const; void damaged(sal_Int32 nExtentsLeft, sal_Int32 nExtentsTop, sal_Int32 nExtentsRight, sal_Int32 nExtentsBottom) const; @@ -428,7 +397,6 @@ public: void LaunchAsyncScroll(GdkEvent const * pEvent); DECL_LINK(AsyncScroll, Timer *, void); -#endif virtual ~GtkSalFrame() override; // SalGraphics or NULL, but two Graphics for all SalFrames @@ -525,7 +493,6 @@ public: // done setting up the clipregion virtual void EndSetClipRegion() override; -#if GTK_CHECK_VERSION(3,0,0) virtual void PositionByToolkit(const tools::Rectangle& rRect, FloatWinPopupFlags nFlags) override; virtual void SetModal(bool bModal) override; virtual bool GetModal() const override; @@ -535,7 +502,6 @@ public: virtual bool UpdatePopover(void* nId, const OUString& rHelpText, vcl::Window* pParent, const tools::Rectangle& rHelpArea) override; virtual bool HidePopover(void* nId) override; virtual weld::Window* GetFrameWeld() const override; -#endif static GtkSalFrame *getFromWindow( GtkWindow *pWindow ); diff --git a/vcl/inc/unx/gtk/gtkgdi.hxx b/vcl/inc/unx/gtk/gtkgdi.hxx index c9b7be49f13e..e19d01205e49 100644 --- a/vcl/inc/unx/gtk/gtkgdi.hxx +++ b/vcl/inc/unx/gtk/gtkgdi.hxx @@ -29,8 +29,6 @@ #include <unx/gtk/gtkframe.hxx> #include <ControlCacheKey.hxx> -#if GTK_CHECK_VERSION(3,0,0) - #include <headless/svpgdi.hxx> #include <textrender.hxx> @@ -394,8 +392,6 @@ protected: ControlState nState, const ImplControlValue& aValue ); }; -#endif // !gtk3 - #endif // INCLUDED_VCL_INC_UNX_GTK_GTKGDI_HXX /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/unx/gtk/gtkinst.hxx b/vcl/inc/unx/gtk/gtkinst.hxx index 65caa384c0ae..78dd9bc6e8b9 100644 --- a/vcl/inc/unx/gtk/gtkinst.hxx +++ b/vcl/inc/unx/gtk/gtkinst.hxx @@ -57,7 +57,6 @@ public: void ThreadsLeave(); }; -#if GTK_CHECK_VERSION(3,0,0) class GtkSalFrame; struct VclToGtkHelper @@ -182,20 +181,10 @@ public: css::uno::Reference<css::datatransfer::XTransferable> const & GetTransferrable() const { return m_xTrans; } }; -#endif - class GtkSalTimer; -#if GTK_CHECK_VERSION(3,0,0) class GtkInstance : public SvpSalInstance -#else -class GtkInstance : public X11SalInstance -#endif { -#if GTK_CHECK_VERSION(3,0,0) typedef SvpSalInstance Superclass_t; -#else - typedef X11SalInstance Superclass_t; -#endif public: GtkInstance( std::unique_ptr<SalYieldMutex> pMutex ); virtual ~GtkInstance() override; @@ -233,7 +222,6 @@ public: virtual css::uno::Reference< css::ui::dialogs::XFolderPicker2 > createFolderPicker( const css::uno::Reference< css::uno::XComponentContext >& ) override; -#if GTK_CHECK_VERSION(3,0,0) virtual css::uno::Reference< css::uno::XInterface > CreateClipboard( const css::uno::Sequence< css::uno::Any >& i_rArguments ) override; virtual css::uno::Reference< css::uno::XInterface > CreateDragSource() override; virtual css::uno::Reference< css::uno::XInterface > CreateDropTarget() override; @@ -241,7 +229,6 @@ public: virtual weld::Builder* CreateBuilder(weld::Widget* pParent, const OUString& rUIRoot, const OUString& rUIFile) override; virtual weld::MessageDialog* CreateMessageDialog(weld::Widget* pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage) override; virtual weld::Window* GetFrameWeld(const css::uno::Reference<css::awt::XWindow>& rWindow) override; -#endif virtual const cairo_font_options_t* GetCairoFontOptions() override; const cairo_font_options_t* GetLastSeenCairoFontOptions() const; @@ -251,15 +238,11 @@ public: std::shared_ptr<vcl::unx::GtkPrintWrapper> const & getPrintWrapper() const; -#if GTK_CHECK_VERSION(3,0,0) void* CreateGStreamerSink(const SystemChildWindow*) override; -#endif private: GtkSalTimer *m_pTimer; -#if GTK_CHECK_VERSION(3,0,0) std::unordered_map< GdkAtom, css::uno::Reference<css::uno::XInterface> > m_aClipboards; -#endif bool IsTimerExpired(); bool bNeedsInit; cairo_font_options_t* m_pLastCairoFontOptions; diff --git a/vcl/inc/unx/gtk/gtkobject.hxx b/vcl/inc/unx/gtk/gtkobject.hxx index 4523e9998abd..f54d7af3f04c 100644 --- a/vcl/inc/unx/gtk/gtkobject.hxx +++ b/vcl/inc/unx/gtk/gtkobject.hxx @@ -29,12 +29,8 @@ class GtkSalObject : public SalObject { SystemEnvData m_aSystemData; GtkWidget* m_pSocket; -#if GTK_CHECK_VERSION(3,0,0) GtkSalFrame* m_pParent; cairo_region_t* m_pRegion; -#else - GdkRegion* m_pRegion; -#endif // signals static gboolean signalButton( GtkWidget*, GdkEventButton*, gpointer ); diff --git a/vcl/inc/unx/gtk/gtkprintwrapper.hxx b/vcl/inc/unx/gtk/gtkprintwrapper.hxx index 4862c8cc2fbc..589c800d77d1 100644 --- a/vcl/inc/unx/gtk/gtkprintwrapper.hxx +++ b/vcl/inc/unx/gtk/gtkprintwrapper.hxx @@ -12,14 +12,11 @@ #include <gtk/gtk.h> -#if defined ENABLE_GTK_PRINT || GTK_CHECK_VERSION(3,0,0) #include <gtk/gtkunixprint.h> #include <osl/module.hxx> #include <sal/types.h> -#endif - namespace vcl { namespace unx @@ -30,7 +27,6 @@ class GtkPrintWrapper private: GtkPrintWrapper(const GtkPrintWrapper&) = delete; GtkPrintWrapper& operator=(const GtkPrintWrapper&) = delete; -#if defined ENABLE_GTK_PRINT || GTK_CHECK_VERSION(3,0,0) public: GtkPrintWrapper(); ~GtkPrintWrapper(); @@ -63,59 +59,6 @@ public: // print selection support, since 2.17.4 void print_unix_dialog_set_support_selection(GtkPrintUnixDialog* dialog, gboolean support_selection) const; void print_unix_dialog_set_has_selection(GtkPrintUnixDialog* dialog, gboolean has_selection) const; - -#if !GTK_CHECK_VERSION(3,0,0) -private: - void impl_load(); - -private: - typedef GtkPageSetup* (* page_setup_new_t)(); - typedef GtkPrintJob* (* print_job_new_t)(const gchar*, GtkPrinter*, GtkPrintSettings*, GtkPageSetup*); - typedef void (* print_job_send_t)(GtkPrintJob*, GtkPrintJobCompleteFunc, gpointer, GDestroyNotify); - typedef gboolean (* print_job_set_source_file_t)(GtkPrintJob*, const gchar*, GError**); - typedef const gchar* (* print_settings_get_t)(GtkPrintSettings*, const gchar*); - typedef gboolean (* print_settings_get_collate_t)(GtkPrintSettings*); - typedef void (* print_settings_set_collate_t)(GtkPrintSettings*, gboolean); - typedef gint (* print_settings_get_n_copies_t)(GtkPrintSettings*); - typedef void (* print_settings_set_n_copies_t)(GtkPrintSettings*, gint); - typedef GtkPageRange* (* print_settings_get_page_ranges_t)(GtkPrintSettings*, gint*); - typedef void (* print_settings_set_print_pages_t)(GtkPrintSettings*, GtkPrintPages); - typedef GtkWidget* (* print_unix_dialog_new_t)(const gchar*, GtkWindow*); - typedef void (* print_unix_dialog_add_custom_tab_t)(GtkPrintUnixDialog*, GtkWidget*, GtkWidget*); - typedef GtkPrinter* (* print_unix_dialog_get_selected_printer_t)(GtkPrintUnixDialog*); - typedef void (* print_unix_dialog_set_manual_capabilities_t)(GtkPrintUnixDialog*, GtkPrintCapabilities); - typedef GtkPrintSettings* (* print_unix_dialog_get_settings_t)(GtkPrintUnixDialog*); - typedef void (* print_unix_dialog_set_settings_t)(GtkPrintUnixDialog*, GtkPrintSettings*); - typedef void (* print_unix_dialog_set_support_selection_t)(GtkPrintUnixDialog*, gboolean); - typedef void (* print_unix_dialog_set_has_selection_t)(GtkPrintUnixDialog*, gboolean); - -private: - osl::Module m_aModule; - - // general printing support, since 2.10.0 - page_setup_new_t m_page_setup_new; - print_job_new_t m_print_job_new; - print_job_send_t m_print_job_send; - print_job_set_source_file_t m_print_job_set_source_file; - print_settings_get_t m_print_settings_get; - print_settings_get_collate_t m_print_settings_get_collate; - print_settings_set_collate_t m_print_settings_set_collate; - print_settings_get_n_copies_t m_print_settings_get_n_copies; - print_settings_set_n_copies_t m_print_settings_set_n_copies; - print_settings_get_page_ranges_t m_print_settings_get_page_ranges; - print_settings_set_print_pages_t m_print_settings_set_print_pages; - print_unix_dialog_new_t m_print_unix_dialog_new; - print_unix_dialog_add_custom_tab_t m_print_unix_dialog_add_custom_tab; - print_unix_dialog_get_selected_printer_t m_print_unix_dialog_get_selected_printer; - print_unix_dialog_set_manual_capabilities_t m_print_unix_dialog_set_manual_capabilities; - print_unix_dialog_get_settings_t m_print_unix_dialog_get_settings; - print_unix_dialog_set_settings_t m_print_unix_dialog_set_settings; - - // print selection support, since 2.17.4 - print_unix_dialog_set_support_selection_t m_print_unix_dialog_set_support_selection; - print_unix_dialog_set_has_selection_t m_print_unix_dialog_set_has_selection; -#endif -#endif }; } diff --git a/vcl/inc/unx/gtk/gtksalmenu.hxx b/vcl/inc/unx/gtk/gtksalmenu.hxx index 2d812cad3962..ddef9ef42310 100644 --- a/vcl/inc/unx/gtk/gtksalmenu.hxx +++ b/vcl/inc/unx/gtk/gtksalmenu.hxx @@ -23,27 +23,8 @@ #include <unotools/tempfile.hxx> #include <vcl/idle.hxx> -#if GTK_CHECK_VERSION(3,0,0) -# define ENABLE_GMENU_INTEGRATION -# include <unx/gtk/glomenu.h> -# include <unx/gtk/gloactiongroup.h> -#elif ENABLE_DBUS && ENABLE_GIO && \ - (GLIB_MAJOR_VERSION > 2 || GLIB_MINOR_VERSION >= 36) -# define ENABLE_GMENU_INTEGRATION -# include <unx/gtk/glomenu.h> -# include <unx/gtk/gloactiongroup.h> -#else -# if !(GLIB_MAJOR_VERSION > 2 || GLIB_MINOR_VERSION >= 32) - typedef void GMenuModel; -# endif -# if !(GLIB_MAJOR_VERSION > 2 || GLIB_MINOR_VERSION >= 28) - typedef void GActionGroup; -# endif -#endif - -#if !GTK_CHECK_VERSION(3,0,0) -typedef void GtkCssProvider; -#endif +#include <unx/gtk/glomenu.h> +#include <unx/gtk/gloactiongroup.h> class MenuItemList; class GtkSalMenuItem; diff --git a/vcl/source/app/salplug.cxx b/vcl/source/app/salplug.cxx index 20604edb7f46..ce3fb551d6af 100644 --- a/vcl/source/app/salplug.cxx +++ b/vcl/source/app/salplug.cxx @@ -95,7 +95,7 @@ SalInstance* tryInstance( const OUString& rModuleBase, bool bForce = false ) * So make sure libgtk+ & co are still mapped into memory when * atk-bridge's atexit handler gets called. */ - if( aUsedModuleBase == "gtk" || aUsedModuleBase == "gtk3" || aUsedModuleBase == "gtk3_kde5" || aUsedModuleBase == "win" ) + if( aUsedModuleBase == "gtk3" || aUsedModuleBase == "gtk3_kde5" || aUsedModuleBase == "win" ) { pCloseModule = nullptr; } @@ -154,12 +154,12 @@ SalInstance* autodetect_plugin() #if ENABLE_GTK3_KDE5 "gtk3_kde5", #endif - "gtk3", "gtk", "gen", nullptr + "gtk3", "gen", nullptr }; static const char* const pStandardFallbackList[] = { - "gtk3", "gtk", "gen", nullptr + "gtk3", "gen", nullptr }; #ifdef HEADLESS_VCLPLUG @@ -259,7 +259,7 @@ SalInstance *CreateSalInstance() #ifdef MACOSX "osx" #else - "gtk3", "gtk", "kf5", "gen" + "gtk3", "kf5", "gen" #endif #endif }; diff --git a/vcl/unx/gtk/a11y/atkaction.cxx b/vcl/unx/gtk/a11y/atkaction.cxx deleted file mode 100644 index 14a172fe6ae3..000000000000 --- a/vcl/unx/gtk/a11y/atkaction.cxx +++ /dev/null @@ -1,275 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "atkwrapper.hxx" - -#include <com/sun/star/accessibility/XAccessibleAction.hpp> -#include <com/sun/star/accessibility/XAccessibleKeyBinding.hpp> - -#include <com/sun/star/awt/Key.hpp> -#include <com/sun/star/awt/KeyModifier.hpp> - -#include <rtl/strbuf.hxx> -#include <algorithm> -#include <map> - -using namespace ::com::sun::star; - -// FIXME -static const gchar * -getAsConst( const OString& rString ) -{ - static const int nMax = 10; - static OString aUgly[nMax]; - static int nIdx = 0; - nIdx = (nIdx + 1) % nMax; - aUgly[nIdx] = rString; - return aUgly[ nIdx ].getStr(); -} - -/// @throws uno::RuntimeException -static css::uno::Reference<css::accessibility::XAccessibleAction> - getAction( AtkAction *action ) -{ - AtkObjectWrapper *pWrap = ATK_OBJECT_WRAPPER( action ); - - if( pWrap ) - { - if( !pWrap->mpAction.is() ) - { - pWrap->mpAction.set(pWrap->mpContext, css::uno::UNO_QUERY); - } - - return pWrap->mpAction; - } - - return css::uno::Reference<css::accessibility::XAccessibleAction>(); -} - -extern "C" { - -static gboolean -action_wrapper_do_action (AtkAction *action, - gint i) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleAction> pAction - = getAction( action ); - if( pAction.is() ) - return pAction->doAccessibleAction( i ); - } - catch(const uno::Exception&) { - g_warning( "Exception in doAccessibleAction()" ); - } - - return FALSE; -} - -static gint -action_wrapper_get_n_actions (AtkAction *action) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleAction> pAction - = getAction( action ); - if( pAction.is() ) - return pAction->getAccessibleActionCount(); - } - catch(const uno::Exception&) { - g_warning( "Exception in getAccessibleActionCount()" ); - } - - return 0; -} - -static const gchar * -action_wrapper_get_description (AtkAction *, gint) -{ - // GAIL implement this only for cells - g_warning( "Not implemented: get_description()" ); - return ""; -} - -static const gchar * -action_wrapper_get_localized_name (AtkAction *, gint) -{ - // GAIL doesn't implement this as well - g_warning( "Not implemented: get_localized_name()" ); - return ""; -} - -#define ACTION_NAME_PAIR( OOoName, AtkName ) \ - std::pair< const OUString, const gchar * > ( OUString( OOoName ), AtkName ) - -static const gchar * -action_wrapper_get_name (AtkAction *action, - gint i) -{ - static std::map< OUString, const gchar * > aNameMap; - - if( aNameMap.empty() ) - { - aNameMap.insert( ACTION_NAME_PAIR( "click", "click" ) ); - aNameMap.insert( ACTION_NAME_PAIR( "select", "click" ) ); - aNameMap.insert( ACTION_NAME_PAIR( "togglePopup", "push" ) ); - } - - try { - css::uno::Reference<css::accessibility::XAccessibleAction> pAction - = getAction( action ); - if( pAction.is() ) - { - std::map< OUString, const gchar * >::iterator iter; - - OUString aDesc( pAction->getAccessibleActionDescription( i ) ); - - iter = aNameMap.find( aDesc ); - if( iter != aNameMap.end() ) - return iter->second; - - std::pair< const OUString, const gchar * > aNewVal( aDesc, - g_strdup( OUStringToConstGChar(aDesc) ) ); - - if( aNameMap.insert( aNewVal ).second ) - return aNewVal.second; - } - } - catch(const uno::Exception&) { - g_warning( "Exception in getAccessibleActionDescription()" ); - } - - return ""; -} - -/* -* GNOME Expects a string in the format: -* -* <mnemonic>;<full-path>;<accelerator> -* -* The keybindings in <full-path> should be separated by ":" -*/ - -static void -appendKeyStrokes(OStringBuffer& rBuffer, const uno::Sequence< awt::KeyStroke >& rKeyStrokes) -{ - for( const auto& rKeyStroke : rKeyStrokes ) - { - if( rKeyStroke.Modifiers & awt::KeyModifier::SHIFT ) - rBuffer.append("<Shift>"); - if( rKeyStroke.Modifiers & awt::KeyModifier::MOD1 ) - rBuffer.append("<Control>"); - if( rKeyStroke.Modifiers & awt::KeyModifier::MOD2 ) - rBuffer.append("<Alt>"); - - if( ( rKeyStroke.KeyCode >= awt::Key::A ) && ( rKeyStroke.KeyCode <= awt::Key::Z ) ) - rBuffer.append( static_cast<sal_Char>( 'a' + ( rKeyStroke.KeyCode - awt::Key::A ) ) ); - else - { - sal_Char c = '\0'; - - switch( rKeyStroke.KeyCode ) - { - case awt::Key::TAB: c = '\t'; break; - case awt::Key::SPACE: c = ' '; break; - case awt::Key::ADD: c = '+'; break; - case awt::Key::SUBTRACT: c = '-'; break; - case awt::Key::MULTIPLY: c = '*'; break; - case awt::Key::DIVIDE: c = '/'; break; - case awt::Key::POINT: c = '.'; break; - case awt::Key::COMMA: c = ','; break; - case awt::Key::LESS: c = '<'; break; - case awt::Key::GREATER: c = '>'; break; - case awt::Key::EQUAL: c = '='; break; - case 0: - break; - default: - g_warning( "Unmapped KeyCode: %d", rKeyStroke.KeyCode ); - break; - } - - if( c != '\0' ) - rBuffer.append( c ); - else - { - // The KeyCode approach did not work, probably a non ascii character - // let's hope that there is a character given in KeyChar. - rBuffer.append( OUStringToGChar( OUString( rKeyStroke.KeyChar ) ) ); - } - } - } -} - -static const gchar * -action_wrapper_get_keybinding (AtkAction *action, - gint i) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleAction> pAction - = getAction( action ); - if( pAction.is() ) - { - uno::Reference< accessibility::XAccessibleKeyBinding > xBinding( pAction->getAccessibleActionKeyBinding( i )); - - if( xBinding.is() ) - { - OStringBuffer aRet; - - sal_Int32 nmax = std::min( xBinding->getAccessibleKeyBindingCount(), sal_Int32(3) ); - for( sal_Int32 n = 0; n < nmax; n++ ) - { - appendKeyStrokes( aRet, xBinding->getAccessibleKeyBinding( n ) ); - - if( n < 2 ) - aRet.append( ';' ); - } - - // !! FIXME !! remember keystroke in wrapper object ? - return getAsConst( aRet.makeStringAndClear() ); - } - } - } - catch(const uno::Exception&) { - g_warning( "Exception in get_keybinding()" ); - } - - return ""; -} - -static gboolean -action_wrapper_set_description (AtkAction *, gint, const gchar *) -{ - return FALSE; -} - -} // extern "C" - -void -actionIfaceInit (AtkActionIface *iface) -{ - g_return_if_fail (iface != nullptr); - - iface->do_action = action_wrapper_do_action; - iface->get_n_actions = action_wrapper_get_n_actions; - iface->get_description = action_wrapper_get_description; - iface->get_keybinding = action_wrapper_get_keybinding; - iface->get_name = action_wrapper_get_name; - iface->get_localized_name = action_wrapper_get_localized_name; - iface->set_description = action_wrapper_set_description; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/a11y/atkbridge.cxx b/vcl/unx/gtk/a11y/atkbridge.cxx deleted file mode 100644 index a74f1a91885f..000000000000 --- a/vcl/unx/gtk/a11y/atkbridge.cxx +++ /dev/null @@ -1,72 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include <unx/gtk/atkbridge.hxx> -#include <unx/gtk/gtkframe.hxx> - -#include "atkfactory.hxx" -#include "atkutil.hxx" -#include "atkwindow.hxx" - -bool InitAtkBridge() -{ -#if GTK_CHECK_VERSION(3,0,0) - ooo_atk_util_ensure_event_listener(); -#else - const char* pVersion = atk_get_toolkit_version(); - if( ! pVersion ) - return false; - - unsigned int major, minor, micro; - - /* check gail minimum version requirements */ - if( sscanf( pVersion, "%u.%u.%u", &major, &minor, µ) < 3 ) - { - // g_warning( "unable to parse gail version number" ); - return false; - } - - if( ( (major << 16) | (minor << 8) | micro ) < ( (1 << 16) | 8 << 8 | 6 ) ) - { - g_warning( "libgail >= 1.8.6 required for accessibility support" ); - return false; - } - - /* Initialize the AtkUtilityWrapper class */ - g_type_class_unref( g_type_class_ref( ooo_atk_util_get_type() ) ); - - /* Initialize the GailWindow wrapper class */ - g_type_class_unref( g_type_class_ref( ooo_window_wrapper_get_type() ) ); - - /* Register AtkObject wrapper factory */ - AtkRegistry * registry = atk_get_default_registry(); - if( registry ) - atk_registry_set_factory_type( registry, OOO_TYPE_FIXED, wrapper_factory_get_type() ); -#endif - return true; -} - -void DeInitAtkBridge() -{ -#if !GTK_CHECK_VERSION(3,0,0) - restore_gail_window_vtable(); -#endif -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/a11y/atkcomponent.cxx b/vcl/unx/gtk/a11y/atkcomponent.cxx deleted file mode 100644 index da5a48eca1f2..000000000000 --- a/vcl/unx/gtk/a11y/atkcomponent.cxx +++ /dev/null @@ -1,387 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "atkwrapper.hxx" -#include <com/sun/star/accessibility/XAccessibleComponent.hpp> -#include <gtk/gtk.h> - -using namespace ::com::sun::star; - -static AtkObjectWrapper* getObjectWrapper(AtkComponent *pComponent) -{ - AtkObjectWrapper *pWrap = nullptr; - if (ATK_IS_OBJECT_WRAPPER(pComponent)) - pWrap = ATK_OBJECT_WRAPPER(pComponent); - else if (GTK_IS_DRAWING_AREA(pComponent)) //when using a GtkDrawingArea as a custom widget in welded gtk3 - { - GtkWidget* pDrawingArea = GTK_WIDGET(pComponent); - AtkObject* pAtkObject = gtk_widget_get_accessible(pDrawingArea); - pWrap = ATK_IS_OBJECT_WRAPPER(pAtkObject) ? ATK_OBJECT_WRAPPER(pAtkObject) : nullptr; - } - return pWrap; -} - -/// @throws uno::RuntimeException -static css::uno::Reference<css::accessibility::XAccessibleComponent> - getComponent(AtkObjectWrapper *pWrap) -{ - if (pWrap) - { - if (!pWrap->mpComponent.is()) - pWrap->mpComponent.set(pWrap->mpContext, css::uno::UNO_QUERY); - return pWrap->mpComponent; - } - - return css::uno::Reference<css::accessibility::XAccessibleComponent>(); -} - -/*****************************************************************************/ - -static awt::Point -translatePoint( css::uno::Reference<accessibility::XAccessibleComponent> const & pComponent, - gint x, gint y, AtkCoordType t) -{ - awt::Point aOrigin( 0, 0 ); - if( t == ATK_XY_SCREEN ) - aOrigin = pComponent->getLocationOnScreen(); - return awt::Point( x - aOrigin.X, y - aOrigin.Y ); -} - -/*****************************************************************************/ - -extern "C" { - -static gboolean -component_wrapper_grab_focus (AtkComponent *component) -{ - AtkObjectWrapper* obj = getObjectWrapper(component); - //if we're a native GtkDrawingArea with custom a11y, use the default toolkit a11y - if (obj && obj->mpOrig) - return atk_component_grab_focus(ATK_COMPONENT(obj->mpOrig)); - - try - { - css::uno::Reference<css::accessibility::XAccessibleComponent> pComponent - = getComponent(obj); - if( pComponent.is() ) - { - pComponent->grabFocus(); - return TRUE; - } - } - catch( const uno::Exception & ) - { - g_warning( "Exception in grabFocus()" ); - } - - return FALSE; -} - -/*****************************************************************************/ - -static gboolean -component_wrapper_contains (AtkComponent *component, - gint x, - gint y, - AtkCoordType coord_type) -{ - AtkObjectWrapper* obj = getObjectWrapper(component); - //if we're a native GtkDrawingArea with custom a11y, use the default toolkit a11y - if (obj && obj->mpOrig) - return atk_component_contains(ATK_COMPONENT(obj->mpOrig), x, y, coord_type); - - try - { - css::uno::Reference<css::accessibility::XAccessibleComponent> pComponent - = getComponent(obj); - if( pComponent.is() ) - return pComponent->containsPoint( translatePoint( pComponent, x, y, coord_type ) ); - } - catch( const uno::Exception & ) - { - g_warning( "Exception in containsPoint()" ); - } - - return FALSE; -} - -/*****************************************************************************/ - -static AtkObject * -component_wrapper_ref_accessible_at_point (AtkComponent *component, - gint x, - gint y, - AtkCoordType coord_type) -{ - AtkObjectWrapper* obj = getObjectWrapper(component); - //if we're a native GtkDrawingArea with custom a11y, use the default toolkit a11y - if (obj && obj->mpOrig) - return atk_component_ref_accessible_at_point(ATK_COMPONENT(obj->mpOrig), x, y, coord_type); - - try - { - css::uno::Reference<css::accessibility::XAccessibleComponent> pComponent - = getComponent(obj); - - if( pComponent.is() ) - { - uno::Reference< accessibility::XAccessible > xAccessible = pComponent->getAccessibleAtPoint( - translatePoint( pComponent, x, y, coord_type ) ); - return atk_object_wrapper_ref( xAccessible ); - } - } - catch( const uno::Exception & ) - { - g_warning( "Exception in getAccessibleAtPoint()" ); - } - - return nullptr; -} - -/*****************************************************************************/ - -static void -component_wrapper_get_position (AtkComponent *component, - gint *x, - gint *y, - AtkCoordType coord_type) -{ - AtkObjectWrapper* obj = getObjectWrapper(component); - //if we're a native GtkDrawingArea with custom a11y, use the default toolkit a11y - if (obj && obj->mpOrig) - { - atk_component_get_extents(ATK_COMPONENT(obj->mpOrig), x, y, nullptr, nullptr, coord_type); - return; - } - - *x = *y = -1; - - try - { - css::uno::Reference<css::accessibility::XAccessibleComponent> pComponent - = getComponent(obj); - if( pComponent.is() ) - { - awt::Point aPos; - - if( coord_type == ATK_XY_SCREEN ) - aPos = pComponent->getLocationOnScreen(); - else - aPos = pComponent->getLocation(); - - *x = aPos.X; - *y = aPos.Y; - } - } - catch( const uno::Exception & ) - { - g_warning( "Exception in getLocation[OnScreen]()" ); - } -} - -/*****************************************************************************/ - -static void -component_wrapper_get_size (AtkComponent *component, - gint *width, - gint *height) -{ - AtkObjectWrapper* obj = getObjectWrapper(component); - //if we're a native GtkDrawingArea with custom a11y, use the default toolkit a11y - if (obj && obj->mpOrig) - { - atk_component_get_extents(ATK_COMPONENT(obj->mpOrig), nullptr, nullptr, width, height, ATK_XY_WINDOW); - return; - } - - *width = *height = -1; - - try - { - css::uno::Reference<css::accessibility::XAccessibleComponent> pComponent - = getComponent(obj); - if( pComponent.is() ) - { - awt::Size aSize = pComponent->getSize(); - *width = aSize.Width; - *height = aSize.Height; - } - } - catch( const uno::Exception & ) - { - g_warning( "Exception in getSize()" ); - } -} - -/*****************************************************************************/ - -static void -component_wrapper_get_extents (AtkComponent *component, - gint *x, - gint *y, - gint *width, - gint *height, - AtkCoordType coord_type) -{ - component_wrapper_get_position( component, x, y, coord_type ); - component_wrapper_get_size( component, width, height ); -} - -/*****************************************************************************/ - -static gboolean -component_wrapper_set_extents (AtkComponent *, gint, gint, gint, gint, AtkCoordType) -{ - g_warning( "AtkComponent::set_extents unimplementable" ); - return FALSE; -} - -/*****************************************************************************/ - -static gboolean -component_wrapper_set_position (AtkComponent *, gint, gint, AtkCoordType) -{ - g_warning( "AtkComponent::set_position unimplementable" ); - return FALSE; -} - -/*****************************************************************************/ - -static gboolean -component_wrapper_set_size (AtkComponent *, gint, gint) -{ - g_warning( "AtkComponent::set_size unimplementable" ); - return FALSE; -} - -/*****************************************************************************/ - -static AtkLayer -component_wrapper_get_layer (AtkComponent *component) -{ - AtkRole role = atk_object_get_role( ATK_OBJECT( component ) ); - AtkLayer layer = ATK_LAYER_WIDGET; - - switch (role) - { - case ATK_ROLE_POPUP_MENU: - case ATK_ROLE_MENU_ITEM: - case ATK_ROLE_CHECK_MENU_ITEM: - case ATK_ROLE_SEPARATOR: - case ATK_ROLE_LIST_ITEM: - layer = ATK_LAYER_POPUP; - break; - case ATK_ROLE_MENU: - { - AtkObject * parent = atk_object_get_parent( ATK_OBJECT( component ) ); - if( atk_object_get_role( parent ) != ATK_ROLE_MENU_BAR ) - layer = ATK_LAYER_POPUP; - } - break; - - case ATK_ROLE_LIST: - { - AtkObject * parent = atk_object_get_parent( ATK_OBJECT( component ) ); - if( atk_object_get_role( parent ) == ATK_ROLE_COMBO_BOX ) - layer = ATK_LAYER_POPUP; - } - break; - - default: - ; - } - - return layer; -} - -/*****************************************************************************/ - -static gint -component_wrapper_get_mdi_zorder (AtkComponent *) -{ - // only needed for ATK_LAYER_MDI (not used) or ATK_LAYER_WINDOW (inherited from GAIL) - return G_MININT; -} - -/*****************************************************************************/ - -// This code is mostly stolen from libgail .. - -static guint -component_wrapper_add_focus_handler (AtkComponent *component, - AtkFocusHandler handler) -{ - GSignalMatchType match_type; - gulong ret; - guint signal_id; - - match_type = GSignalMatchType(G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC); - signal_id = g_signal_lookup( "focus-event", ATK_TYPE_OBJECT ); - - ret = g_signal_handler_find( component, match_type, signal_id, 0, nullptr, - static_cast<gpointer>(&handler), nullptr); - if (!ret) - { - return g_signal_connect_closure_by_id (component, - signal_id, 0, - g_cclosure_new ( - G_CALLBACK (handler), nullptr, - nullptr), - FALSE); - } - else - { - return 0; - } -} - -/*****************************************************************************/ - -static void -component_wrapper_remove_focus_handler (AtkComponent *component, - guint handler_id) -{ - g_signal_handler_disconnect (component, handler_id); -} - -/*****************************************************************************/ - -} // extern "C" - -void -componentIfaceInit (AtkComponentIface *iface) -{ - g_return_if_fail (iface != nullptr); - - iface->add_focus_handler = component_wrapper_add_focus_handler; - iface->contains = component_wrapper_contains; - iface->get_extents = component_wrapper_get_extents; - iface->get_layer = component_wrapper_get_layer; - iface->get_mdi_zorder = component_wrapper_get_mdi_zorder; - iface->get_position = component_wrapper_get_position; - iface->get_size = component_wrapper_get_size; - iface->grab_focus = component_wrapper_grab_focus; - iface->ref_accessible_at_point = component_wrapper_ref_accessible_at_point; - iface->remove_focus_handler = component_wrapper_remove_focus_handler; - iface->set_extents = component_wrapper_set_extents; - iface->set_position = component_wrapper_set_position; - iface->set_size = component_wrapper_set_size; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/a11y/atkeditabletext.cxx b/vcl/unx/gtk/a11y/atkeditabletext.cxx deleted file mode 100644 index 49d3eb9ccfc9..000000000000 --- a/vcl/unx/gtk/a11y/atkeditabletext.cxx +++ /dev/null @@ -1,194 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "atkwrapper.hxx" -#include "atktextattributes.hxx" - -#include <com/sun/star/accessibility/XAccessibleEditableText.hpp> -#include <com/sun/star/accessibility/TextSegment.hpp> - -#include <string.h> - -using namespace ::com::sun::star; - -/// @throws uno::RuntimeException -static css::uno::Reference<css::accessibility::XAccessibleEditableText> - getEditableText( AtkEditableText *pEditableText ) -{ - AtkObjectWrapper *pWrap = ATK_OBJECT_WRAPPER( pEditableText ); - if( pWrap ) - { - if( !pWrap->mpEditableText.is() ) - { - pWrap->mpEditableText.set(pWrap->mpContext, css::uno::UNO_QUERY); - } - - return pWrap->mpEditableText; - } - - return css::uno::Reference<css::accessibility::XAccessibleEditableText>(); -} - -/*****************************************************************************/ - -extern "C" { - -static gboolean -editable_text_wrapper_set_run_attributes( AtkEditableText *text, - AtkAttributeSet *attribute_set, - gint nStartOffset, - gint nEndOffset) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleEditableText> - pEditableText = getEditableText( text ); - if( pEditableText.is() ) - { - uno::Sequence< beans::PropertyValue > aAttributeList; - - if( attribute_set_map_to_property_values( attribute_set, aAttributeList ) ) - return pEditableText->setAttributes(nStartOffset, nEndOffset, aAttributeList); - } - } - catch(const uno::Exception&) { - g_warning( "Exception in setAttributes()" ); - } - - return FALSE; -} - -static void -editable_text_wrapper_set_text_contents( AtkEditableText *text, - const gchar *string ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleEditableText> - pEditableText = getEditableText( text ); - if( pEditableText.is() ) - { - OUString aString ( string, strlen(string), RTL_TEXTENCODING_UTF8 ); - pEditableText->setText( aString ); - } - } - catch(const uno::Exception&) { - g_warning( "Exception in setText()" ); - } -} - -static void -editable_text_wrapper_insert_text( AtkEditableText *text, - const gchar *string, - gint length, - gint *pos ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleEditableText> - pEditableText = getEditableText( text ); - if( pEditableText.is() ) - { - OUString aString ( string, length, RTL_TEXTENCODING_UTF8 ); - if( pEditableText->insertText( aString, *pos ) ) - *pos += length; - } - } - catch(const uno::Exception&) { - g_warning( "Exception in insertText()" ); - } -} - -static void -editable_text_wrapper_cut_text( AtkEditableText *text, - gint start, - gint end ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleEditableText> - pEditableText = getEditableText( text ); - if( pEditableText.is() ) - pEditableText->cutText( start, end ); - } - catch(const uno::Exception&) { - g_warning( "Exception in cutText()" ); - } -} - -static void -editable_text_wrapper_delete_text( AtkEditableText *text, - gint start, - gint end ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleEditableText> - pEditableText = getEditableText( text ); - if( pEditableText.is() ) - pEditableText->deleteText( start, end ); - } - catch(const uno::Exception&) { - g_warning( "Exception in deleteText()" ); - } -} - -static void -editable_text_wrapper_paste_text( AtkEditableText *text, - gint pos ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleEditableText> - pEditableText = getEditableText( text ); - if( pEditableText.is() ) - pEditableText->pasteText( pos ); - } - catch(const uno::Exception&) { - g_warning( "Exception in pasteText()" ); - } -} - -static void -editable_text_wrapper_copy_text( AtkEditableText *text, - gint start, - gint end ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleEditableText> - pEditableText = getEditableText( text ); - if( pEditableText.is() ) - pEditableText->copyText( start, end ); - } - catch(const uno::Exception&) { - g_warning( "Exception in copyText()" ); - } -} - -} // extern "C" - -void -editableTextIfaceInit (AtkEditableTextIface *iface) -{ - g_return_if_fail (iface != nullptr); - - iface->set_text_contents = editable_text_wrapper_set_text_contents; - iface->insert_text = editable_text_wrapper_insert_text; - iface->copy_text = editable_text_wrapper_copy_text; - iface->cut_text = editable_text_wrapper_cut_text; - iface->delete_text = editable_text_wrapper_delete_text; - iface->paste_text = editable_text_wrapper_paste_text; - iface->set_run_attributes = editable_text_wrapper_set_run_attributes; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/a11y/atkfactory.cxx b/vcl/unx/gtk/a11y/atkfactory.cxx deleted file mode 100644 index 3a776b20dcc7..000000000000 --- a/vcl/unx/gtk/a11y/atkfactory.cxx +++ /dev/null @@ -1,195 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include <unx/gtk/gtkframe.hxx> -#include <vcl/window.hxx> -#include "atkwrapper.hxx" -#include "atkfactory.hxx" -#include "atkregistry.hxx" - -using namespace ::com::sun::star; - -extern "C" { - -/* - * Instances of this dummy object class are returned whenever we have to - * create an AtkObject, but can't touch the OOo object anymore since it - * is already disposed. - */ - -static AtkStateSet * -noop_wrapper_ref_state_set( AtkObject * ) -{ - AtkStateSet *state_set = atk_state_set_new(); - atk_state_set_add_state( state_set, ATK_STATE_DEFUNCT ); - return state_set; -} - -static void -atk_noop_object_wrapper_class_init(AtkNoOpObjectClass *klass) -{ - AtkObjectClass *atk_class = ATK_OBJECT_CLASS( klass ); - atk_class->ref_state_set = noop_wrapper_ref_state_set; -} - -static GType -atk_noop_object_wrapper_get_type() -{ - static GType type = 0; - - if (!type) - { - static const GTypeInfo typeInfo = - { - sizeof (AtkNoOpObjectClass), - nullptr, - nullptr, - reinterpret_cast<GClassInitFunc>(atk_noop_object_wrapper_class_init), - nullptr, - nullptr, - sizeof (AtkObjectWrapper), - 0, - nullptr, - nullptr - } ; - - type = g_type_register_static (ATK_TYPE_OBJECT, "OOoAtkNoOpObj", &typeInfo, GTypeFlags(0)) ; - } - return type; -} - -static AtkObject* -atk_noop_object_wrapper_new() -{ - AtkObject *accessible; - - accessible = static_cast<AtkObject *>(g_object_new (atk_noop_object_wrapper_get_type(), nullptr)); - g_return_val_if_fail (accessible != nullptr, nullptr); - - accessible->role = ATK_ROLE_INVALID; - accessible->layer = ATK_LAYER_INVALID; - - return accessible; -} - -/* - * The wrapper factory - */ - -static GType -wrapper_factory_get_accessible_type() -{ - return atk_object_wrapper_get_type(); -} - -static AtkObject* -wrapper_factory_create_accessible( GObject *obj ) -{ -#if GTK_CHECK_VERSION(3,0,0) - GtkWidget* pEventBox = gtk_widget_get_parent(GTK_WIDGET(obj)); - - // gail_container_real_remove_gtk tries to re-instantiate an accessible - // for a widget that is about to vanish .. - if (!pEventBox) - return atk_noop_object_wrapper_new(); - - GtkWidget* pTopLevelGrid = gtk_widget_get_parent(pEventBox); - if (!pTopLevelGrid) - return atk_noop_object_wrapper_new(); - - GtkWidget* pTopLevel = gtk_widget_get_parent(pTopLevelGrid); - if (!pTopLevel) - return atk_noop_object_wrapper_new(); -#else - GtkWidget* pTopLevel = gtk_widget_get_parent(GTK_WIDGET(obj)); - - // gail_container_real_remove_gtk tries to re-instantiate an accessible - // for a widget that is about to vanish .. - if (!pTopLevel) - return atk_noop_object_wrapper_new(); -#endif - - GtkSalFrame* pFrame = GtkSalFrame::getFromWindow(GTK_WINDOW(pTopLevel)); - g_return_val_if_fail( pFrame != nullptr, nullptr ); - - vcl::Window* pFrameWindow = pFrame->GetWindow(); - if( pFrameWindow ) - { - vcl::Window* pWindow = pFrameWindow; - - // skip accessible objects already exposed by the frame objects - if( WindowType::BORDERWINDOW == pWindow->GetType() ) - pWindow = pFrameWindow->GetAccessibleChildWindow(0); - - if( pWindow ) - { - uno::Reference< accessibility::XAccessible > xAccessible = pWindow->GetAccessible(); - if( xAccessible.is() ) - { - AtkObject *accessible = ooo_wrapper_registry_get( xAccessible ); - - if( accessible ) - g_object_ref( G_OBJECT(accessible) ); - else - accessible = atk_object_wrapper_new( xAccessible, gtk_widget_get_accessible(pTopLevel) ); - - return accessible; - } - } - } - - return nullptr; -} - -AtkObject* ooo_fixed_get_accessible(GtkWidget *obj) -{ - return wrapper_factory_create_accessible(G_OBJECT(obj)); -} - -static void -wrapper_factory_class_init( AtkObjectFactoryClass *klass ) -{ - klass->create_accessible = wrapper_factory_create_accessible; - klass->get_accessible_type = wrapper_factory_get_accessible_type; -} - -GType -wrapper_factory_get_type() -{ - static GType t = 0; - - if (!t) { - static const GTypeInfo tinfo = - { - sizeof (AtkObjectFactoryClass), - nullptr, nullptr, reinterpret_cast<GClassInitFunc>(wrapper_factory_class_init), - nullptr, nullptr, sizeof (AtkObjectFactory), 0, nullptr, nullptr - }; - - t = g_type_register_static ( - ATK_TYPE_OBJECT_FACTORY, "OOoAtkObjectWrapperFactory", - &tinfo, GTypeFlags(0)); - } - - return t; -} - -} // extern C - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/a11y/atkhypertext.cxx b/vcl/unx/gtk/a11y/atkhypertext.cxx deleted file mode 100644 index ab94126dfc51..000000000000 --- a/vcl/unx/gtk/a11y/atkhypertext.cxx +++ /dev/null @@ -1,273 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "atkwrapper.hxx" - -#include <com/sun/star/accessibility/XAccessibleHypertext.hpp> - -using namespace ::com::sun::star; - -// ---------------------- AtkHyperlink ---------------------- - -struct HyperLink { - AtkHyperlink const atk_hyper_link; - - uno::Reference< accessibility::XAccessibleHyperlink > xLink; -}; - -static uno::Reference< accessibility::XAccessibleHyperlink > const & - getHyperlink( AtkHyperlink *pHyperlink ) -{ - HyperLink *pLink = reinterpret_cast<HyperLink *>(pHyperlink); - return pLink->xLink; -} - -static GObjectClass *hyper_parent_class = nullptr; - -extern "C" { - -static void -hyper_link_finalize (GObject *obj) -{ - HyperLink *hl = reinterpret_cast<HyperLink *>(obj); - hl->xLink.clear(); - hyper_parent_class->finalize (obj); -} - -static gchar * -hyper_link_get_uri( AtkHyperlink *pLink, - gint i ) -{ - try { - uno::Any aAny = getHyperlink( pLink )->getAccessibleActionObject( i ); - OUString aUri = aAny.get< OUString > (); - return OUStringToGChar(aUri); - } - catch(const uno::Exception&) { - g_warning( "Exception in hyper_link_get_uri" ); - } - return nullptr; -} - -static AtkObject * -hyper_link_get_object( AtkHyperlink *, - gint ) -{ - g_warning( "FIXME: hyper_link_get_object unimplemented" ); - return nullptr; -} -static gint -hyper_link_get_end_index( AtkHyperlink *pLink ) -{ - try { - return getHyperlink( pLink )->getEndIndex(); - } - catch(const uno::Exception&) { - } - return -1; -} -static gint -hyper_link_get_start_index( AtkHyperlink *pLink ) -{ - try { - return getHyperlink( pLink )->getStartIndex(); - } - catch(const uno::Exception&) { - } - return -1; -} -static gboolean -hyper_link_is_valid( AtkHyperlink *pLink ) -{ - try { - return getHyperlink( pLink )->isValid(); - } - catch(const uno::Exception&) { - } - return FALSE; -} -static gint -hyper_link_get_n_anchors( AtkHyperlink *pLink ) -{ - try { - return getHyperlink( pLink )->getAccessibleActionCount(); - } - catch(const uno::Exception&) { - } - return 0; -} - -static guint -hyper_link_link_state( AtkHyperlink * ) -{ - g_warning( "FIXME: hyper_link_link_state unimplemented" ); - return 0; -} -static gboolean -hyper_link_is_selected_link( AtkHyperlink * ) -{ - g_warning( "FIXME: hyper_link_is_selected_link unimplemented" ); - return FALSE; -} - -static void -hyper_link_class_init (AtkHyperlinkClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - gobject_class->finalize = hyper_link_finalize; - - hyper_parent_class = static_cast<GObjectClass *>(g_type_class_peek_parent (klass)); - - klass->get_uri = hyper_link_get_uri; - klass->get_object = hyper_link_get_object; - klass->get_end_index = hyper_link_get_end_index; - klass->get_start_index = hyper_link_get_start_index; - klass->is_valid = hyper_link_is_valid; - klass->get_n_anchors = hyper_link_get_n_anchors; - klass->link_state = hyper_link_link_state; - klass->is_selected_link = hyper_link_is_selected_link; -} - -static GType -hyper_link_get_type() -{ - static GType type = 0; - - if (!type) { - static const GTypeInfo tinfo = { - sizeof (AtkHyperlinkClass), - nullptr, /* base init */ - nullptr, /* base finalize */ - reinterpret_cast<GClassInitFunc>(hyper_link_class_init), - nullptr, /* class finalize */ - nullptr, /* class data */ - sizeof (HyperLink), /* instance size */ - 0, /* nb preallocs */ - nullptr, /* instance init */ - nullptr /* value table */ - }; - - static const GInterfaceInfo atk_action_info = { - reinterpret_cast<GInterfaceInitFunc>(actionIfaceInit), - nullptr, - nullptr - }; - - type = g_type_register_static (ATK_TYPE_HYPERLINK, - "OOoAtkObjHyperLink", &tinfo, - GTypeFlags(0)); - g_type_add_interface_static (type, ATK_TYPE_ACTION, - &atk_action_info); - } - - return type; -} - -// ---------------------- AtkHyperText ---------------------- - -/// @throws uno::RuntimeException -static css::uno::Reference<css::accessibility::XAccessibleHypertext> - getHypertext( AtkHypertext *pHypertext ) -{ - AtkObjectWrapper *pWrap = ATK_OBJECT_WRAPPER( pHypertext ); - if( pWrap ) - { - if( !pWrap->mpHypertext.is() ) - { - pWrap->mpHypertext.set(pWrap->mpContext, css::uno::UNO_QUERY); - } - - return pWrap->mpHypertext; - } - - return css::uno::Reference<css::accessibility::XAccessibleHypertext>(); -} - -static AtkHyperlink * -hypertext_get_link( AtkHypertext *hypertext, - gint link_index) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleHypertext> pHypertext - = getHypertext( hypertext ); - if( pHypertext.is() ) - { - HyperLink *pLink = static_cast<HyperLink *>(g_object_new( hyper_link_get_type(), nullptr )); - pLink->xLink = pHypertext->getHyperLink( link_index ); - if( !pLink->xLink.is() ) { - g_object_unref( G_OBJECT( pLink ) ); - pLink = nullptr; - } - return ATK_HYPERLINK( pLink ); - } - } - catch(const uno::Exception&) { - g_warning( "Exception in getHyperLink()" ); - } - - return nullptr; -} - -static gint -hypertext_get_n_links( AtkHypertext *hypertext ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleHypertext> pHypertext - = getHypertext( hypertext ); - if( pHypertext.is() ) - return pHypertext->getHyperLinkCount(); - } - catch(const uno::Exception&) { - g_warning( "Exception in getHyperLinkCount()" ); - } - - return 0; -} - -static gint -hypertext_get_link_index( AtkHypertext *hypertext, - gint index) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleHypertext> pHypertext - = getHypertext( hypertext ); - if( pHypertext.is() ) - return pHypertext->getHyperLinkIndex( index ); - } - catch(const uno::Exception&) { - g_warning( "Exception in getHyperLinkIndex()" ); - } - - return 0; -} - -} // extern "C" - -void -hypertextIfaceInit (AtkHypertextIface *iface) -{ - g_return_if_fail (iface != nullptr); - - iface->get_link = hypertext_get_link; - iface->get_n_links = hypertext_get_n_links; - iface->get_link_index = hypertext_get_link_index; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/a11y/atkimage.cxx b/vcl/unx/gtk/a11y/atkimage.cxx deleted file mode 100644 index acd43f467690..000000000000 --- a/vcl/unx/gtk/a11y/atkimage.cxx +++ /dev/null @@ -1,131 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "atkwrapper.hxx" - -#include <com/sun/star/accessibility/XAccessibleImage.hpp> - -using namespace ::com::sun::star; - -// FIXME -static const gchar * -getAsConst( const OUString& rString ) -{ - static const int nMax = 10; - static OString aUgly[nMax]; - static int nIdx = 0; - nIdx = (nIdx + 1) % nMax; - aUgly[nIdx] = OUStringToOString( rString, RTL_TEXTENCODING_UTF8 ); - return aUgly[ nIdx ].getStr(); -} - -/// @throws uno::RuntimeException -static css::uno::Reference<css::accessibility::XAccessibleImage> - getImage( AtkImage *pImage ) -{ - AtkObjectWrapper *pWrap = ATK_OBJECT_WRAPPER( pImage ); - if( pWrap ) - { - if( !pWrap->mpImage.is() ) - { - pWrap->mpImage.set(pWrap->mpContext, css::uno::UNO_QUERY); - } - - return pWrap->mpImage; - } - - return css::uno::Reference<css::accessibility::XAccessibleImage>(); -} - -extern "C" { - -static const gchar * -image_get_image_description( AtkImage *image ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleImage> pImage - = getImage( image ); - if( pImage.is() ) - return getAsConst( pImage->getAccessibleImageDescription() ); - } - catch(const uno::Exception&) { - g_warning( "Exception in getAccessibleImageDescription()" ); - } - - return nullptr; -} - -static void -image_get_image_position( AtkImage *image, - gint *x, - gint *y, - AtkCoordType coord_type ) -{ - *x = *y = -1; - if( ATK_IS_COMPONENT( image ) ) - { - SAL_WNODEPRECATED_DECLARATIONS_PUSH - atk_component_get_position( ATK_COMPONENT( image ), x, y, coord_type ); - SAL_WNODEPRECATED_DECLARATIONS_POP - } - else - g_warning( "FIXME: no image position information" ); -} - -static void -image_get_image_size( AtkImage *image, - gint *width, - gint *height ) -{ - *width = *height = -1; - try { - css::uno::Reference<css::accessibility::XAccessibleImage> pImage - = getImage( image ); - if( pImage.is() ) - { - *width = pImage->getAccessibleImageWidth(); - *height = pImage->getAccessibleImageHeight(); - } - } - catch(const uno::Exception&) { - g_warning( "Exception in getAccessibleImageHeight() or Width" ); - } -} - -static gboolean -image_set_image_description( AtkImage *, const gchar * ) -{ - g_warning ("FIXME: no set image description"); - return FALSE; -} - -} // extern "C" - -void -imageIfaceInit (AtkImageIface *iface) -{ - g_return_if_fail (iface != nullptr); - - iface->set_image_description = image_set_image_description; - iface->get_image_description = image_get_image_description; - iface->get_image_position = image_get_image_position; - iface->get_image_size = image_get_image_size; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/a11y/atklistener.cxx b/vcl/unx/gtk/a11y/atklistener.cxx deleted file mode 100644 index c30bc638bced..000000000000 --- a/vcl/unx/gtk/a11y/atklistener.cxx +++ /dev/null @@ -1,739 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifdef AIX -#define _LINUX_SOURCE_COMPAT -#include <sys/timer.h> -#undef _LINUX_SOURCE_COMPAT -#endif - -#include <com/sun/star/accessibility/TextSegment.hpp> -#include <com/sun/star/accessibility/AccessibleEventId.hpp> -#include <com/sun/star/accessibility/AccessibleStateType.hpp> -#include <com/sun/star/accessibility/AccessibleTableModelChange.hpp> -#include <com/sun/star/accessibility/AccessibleTableModelChangeType.hpp> -#include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp> -#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> - -#include "atklistener.hxx" -#include "atkwrapper.hxx" -#include <vcl/svapp.hxx> - -#include <rtl/ref.hxx> -#include <sal/log.hxx> - -#define DEBUG_ATK_LISTENER 0 - -#if DEBUG_ATK_LISTENER -#include <iostream> -#include <sstream> -#endif - -using namespace com::sun::star; - -AtkListener::AtkListener( AtkObjectWrapper* pWrapper ) : mpWrapper( pWrapper ) -{ - if( mpWrapper ) - { - g_object_ref( mpWrapper ); - updateChildList( mpWrapper->mpContext ); - } -} - -AtkListener::~AtkListener() -{ - if( mpWrapper ) - g_object_unref( mpWrapper ); -} - -/*****************************************************************************/ - -static AtkStateType mapState( const uno::Any &rAny ) -{ - sal_Int16 nState = accessibility::AccessibleStateType::INVALID; - rAny >>= nState; - return mapAtkState( nState ); -} - -/*****************************************************************************/ - -extern "C" { - // rhbz#1001768 - down to horrific problems releasing the solar mutex - // while destroying a Window - which occurs inside these notifications. - static gboolean - idle_defunc_state_change( AtkObject *atk_obj ) - { - SolarMutexGuard aGuard; - - // This is an equivalent to a state change to DEFUNC(T). - atk_object_notify_state_change( atk_obj, ATK_STATE_DEFUNCT, TRUE ); - if( atk_get_focus_object() == atk_obj ) - { - SAL_WNODEPRECATED_DECLARATIONS_PUSH - atk_focus_tracker_notify( nullptr ); - SAL_WNODEPRECATED_DECLARATIONS_POP - } - g_object_unref( G_OBJECT( atk_obj ) ); - return false; - } -} - -// XEventListener implementation -void AtkListener::disposing( const lang::EventObject& ) -{ - if( mpWrapper ) - { - AtkObject *atk_obj = ATK_OBJECT( mpWrapper ); - - // Release all interface references to avoid shutdown problems with - // global mutex - atk_object_wrapper_dispose( mpWrapper ); - - g_idle_add( reinterpret_cast<GSourceFunc>(idle_defunc_state_change), - g_object_ref( G_OBJECT( atk_obj ) ) ); - - // Release the wrapper object so that it can vanish .. - g_object_unref( mpWrapper ); - mpWrapper = nullptr; - } -} - -/*****************************************************************************/ - -static AtkObject *getObjFromAny( const uno::Any &rAny ) -{ - uno::Reference< accessibility::XAccessible > xAccessible; - rAny >>= xAccessible; - return xAccessible.is() ? atk_object_wrapper_ref( xAccessible ) : nullptr; -} - -/*****************************************************************************/ - -// Updates the child list held to provide the old IndexInParent on children_changed::remove -void AtkListener::updateChildList( - css::uno::Reference<css::accessibility::XAccessibleContext> const & - pContext) -{ - m_aChildList.clear(); - - uno::Reference< accessibility::XAccessibleStateSet > xStateSet = pContext->getAccessibleStateSet(); - if( xStateSet.is() - && !xStateSet->contains(accessibility::AccessibleStateType::DEFUNC) - && !xStateSet->contains(accessibility::AccessibleStateType::MANAGES_DESCENDANTS) ) - { - sal_Int32 nChildren = pContext->getAccessibleChildCount(); - m_aChildList.resize(nChildren); - for(sal_Int32 n = 0; n < nChildren; n++) - { - try - { - m_aChildList[n] = pContext->getAccessibleChild(n); - } - catch (lang::IndexOutOfBoundsException const&) - { - sal_Int32 nChildren2 = pContext->getAccessibleChildCount(); - assert(nChildren2 <= n && "consistency?"); - m_aChildList.resize(std::min(nChildren2, n)); - break; - } - } - } -} - -/*****************************************************************************/ - -void AtkListener::handleChildAdded( - const uno::Reference< accessibility::XAccessibleContext >& rxParent, - const uno::Reference< accessibility::XAccessible>& rxAccessible) -{ - AtkObject * pChild = rxAccessible.is() ? atk_object_wrapper_ref( rxAccessible ) : nullptr; - - if( pChild ) - { - updateChildList(rxParent); - - atk_object_wrapper_add_child( mpWrapper, pChild, - atk_object_get_index_in_parent( pChild )); - - g_object_unref( pChild ); - } -} - -/*****************************************************************************/ - -void AtkListener::handleChildRemoved( - const uno::Reference< accessibility::XAccessibleContext >& rxParent, - const uno::Reference< accessibility::XAccessible>& rxChild) -{ - sal_Int32 nIndex = -1; - - // Locate the child in the children list - size_t n, nmax = m_aChildList.size(); - for( n = 0; n < nmax; ++n ) - { - if( rxChild == m_aChildList[n] ) - { - nIndex = n; - break; - } - } - - // FIXME: two problems here: - // a) we get child-removed events for objects that are no real children - // in the accessibility hierarchy or have been removed before due to - // some child removing batch. - // b) spi_atk_bridge_signal_listener ignores the given parameters - // for children_changed events and always asks the parent for the - // 0. child, which breaks somehow on vanishing list boxes. - // Ignoring "remove" events for objects not in the m_aChildList - // for now. - if( nIndex >= 0 ) - { - uno::Reference<accessibility::XAccessibleEventBroadcaster> xBroadcaster( - rxChild->getAccessibleContext(), uno::UNO_QUERY); - - if (xBroadcaster.is()) - { - uno::Reference<accessibility::XAccessibleEventListener> xListener(this); - xBroadcaster->removeAccessibleEventListener(xListener); - } - - updateChildList(rxParent); - - AtkObject * pChild = atk_object_wrapper_ref( rxChild, false ); - if( pChild ) - { - atk_object_wrapper_remove_child( mpWrapper, pChild, nIndex ); - g_object_unref( pChild ); - } - } -} - -/*****************************************************************************/ - -void AtkListener::handleInvalidateChildren( - const uno::Reference< accessibility::XAccessibleContext >& rxParent) -{ - // Send notifications for all previous children - size_t n = m_aChildList.size(); - while( n-- > 0 ) - { - if( m_aChildList[n].is() ) - { - AtkObject * pChild = atk_object_wrapper_ref( m_aChildList[n], false ); - if( pChild ) - { - atk_object_wrapper_remove_child( mpWrapper, pChild, n ); - g_object_unref( pChild ); - } - } - } - - updateChildList(rxParent); - - // Send notifications for all new children - size_t nmax = m_aChildList.size(); - for( n = 0; n < nmax; ++n ) - { - if( m_aChildList[n].is() ) - { - AtkObject * pChild = atk_object_wrapper_ref( m_aChildList[n] ); - - if( pChild ) - { - atk_object_wrapper_add_child( mpWrapper, pChild, n ); - g_object_unref( pChild ); - } - } - } -} - -/*****************************************************************************/ - -static uno::Reference< accessibility::XAccessibleContext > -getAccessibleContextFromSource( const uno::Reference< uno::XInterface >& rxSource ) -{ - uno::Reference< accessibility::XAccessibleContext > xContext(rxSource, uno::UNO_QUERY); - if( ! xContext.is() ) - { - g_warning( "ERROR: Event source does not implement XAccessibleContext" ); - - // Second try - query for XAccessible, which should give us access to - // XAccessibleContext. - uno::Reference< accessibility::XAccessible > xAccessible(rxSource, uno::UNO_QUERY); - if( xAccessible.is() ) - xContext = xAccessible->getAccessibleContext(); - } - - return xContext; -} - -#if DEBUG_ATK_LISTENER - -namespace { - -void printNotifyEvent( const accessibility::AccessibleEventObject& rEvent ) -{ - static std::vector<const char*> aLabels = { - 0, - "NAME_CHANGED", // 01 - "DESCRIPTION_CHANGED", // 02 - "ACTION_CHANGED", // 03 - "STATE_CHANGED", // 04 - "ACTIVE_DESCENDANT_CHANGED", // 05 - "BOUNDRECT_CHANGED", // 06 - "CHILD", // 07 - "INVALIDATE_ALL_CHILDREN", // 08 - "SELECTION_CHANGED", // 09 - "VISIBLE_DATA_CHANGED", // 10 - "VALUE_CHANGED", // 11 - "CONTENT_FLOWS_FROM_RELATION_CHANGED", // 12 - "CONTENT_FLOWS_TO_RELATION_CHANGED", // 13 - "CONTROLLED_BY_RELATION_CHANGED", // 14 - "CONTROLLER_FOR_RELATION_CHANGED", // 15 - "LABEL_FOR_RELATION_CHANGED", // 16 - "LABELED_BY_RELATION_CHANGED", // 17 - "MEMBER_OF_RELATION_CHANGED", // 18 - "SUB_WINDOW_OF_RELATION_CHANGED", // 19 - "CARET_CHANGED", // 20 - "TEXT_SELECTION_CHANGED", // 21 - "TEXT_CHANGED", // 22 - "TEXT_ATTRIBUTE_CHANGED", // 23 - "HYPERTEXT_CHANGED", // 24 - "TABLE_CAPTION_CHANGED", // 25 - "TABLE_COLUMN_DESCRIPTION_CHANGED", // 26 - "TABLE_COLUMN_HEADER_CHANGED", // 27 - "TABLE_MODEL_CHANGED", // 28 - "TABLE_ROW_DESCRIPTION_CHANGED", // 29 - "TABLE_ROW_HEADER_CHANGED", // 30 - "TABLE_SUMMARY_CHANGED", // 31 - "LISTBOX_ENTRY_EXPANDED", // 32 - "LISTBOX_ENTRY_COLLAPSED", // 33 - "ACTIVE_DESCENDANT_CHANGED_NOFOCUS", // 34 - "SELECTION_CHANGED_ADD", // 35 - "SELECTION_CHANGED_REMOVE", // 36 - "SELECTION_CHANGED_WITHIN", // 37 - "PAGE_CHANGED", // 38 - "SECTION_CHANGED", // 39 - "COLUMN_CHANGED", // 40 - "ROLE_CHANGED", // 41 - }; - - static std::vector<const char*> aStates = { - "INVALID", // 00 - "ACTIVE", // 01 - "ARMED", // 02 - "BUSY", // 03 - "CHECKED", // 04 - "DEFUNC", // 05 - "EDITABLE", // 06 - "ENABLED", // 07 - "EXPANDABLE", // 08 - "EXPANDED", // 09 - "FOCUSABLE", // 10 - "FOCUSED", // 11 - "HORIZONTAL", // 12 - "ICONIFIED", // 13 - "INDETERMINATE", // 14 - "MANAGES_DESCENDANTS", // 15 - "MODAL", // 16 - "MULTI_LINE", // 17 - "MULTI_SELECTABLE", // 18 - "OPAQUE", // 19 - "PRESSED", // 20 - "RESIZABLE", // 21 - "SELECTABLE", // 22 - "SELECTED", // 23 - "SENSITIVE", // 24 - "SHOWING", // 25 - "SINGLE_LINE", // 26 - "STALE", // 27 - "TRANSIENT", // 28 - "VERTICAL", // 29 - "VISIBLE", // 30 - "MOVEABLE", // 31 - "DEFAULT", // 32 - "OFFSCREEN", // 33 - "COLLAPSE", // 34 - }; - - auto getOrUnknown = [](const std::vector<const char*>& rCont, size_t nIndex) -> std::string - { - return (nIndex < rCont.size()) ? rCont[nIndex] : "<unknown>"; - }; - - std::ostringstream os; - os << "--" << std::endl; - os << "* event = " << getOrUnknown(aLabels, rEvent.EventId) << std::endl; - - switch (rEvent.EventId) - { - case accessibility::AccessibleEventId::STATE_CHANGED: - { - sal_Int16 nState; - if (rEvent.OldValue >>= nState) - os << " * old state = " << getOrUnknown(aStates, nState); - if (rEvent.NewValue >>= nState) - os << " * new state = " << getOrUnknown(aStates, nState); - - os << std::endl; - break; - } - default: - ; - } - - std::cout << os.str(); -} - -} - -#endif - -void AtkListener::notifyEvent( const accessibility::AccessibleEventObject& aEvent ) -{ - if( !mpWrapper ) - return; - - AtkObject *atk_obj = ATK_OBJECT( mpWrapper ); - - switch( aEvent.EventId ) - { - // AtkObject signals: - // Hierarchy signals - case accessibility::AccessibleEventId::CHILD: - { - uno::Reference< accessibility::XAccessibleContext > xParent; - uno::Reference< accessibility::XAccessible > xChild; - - xParent = getAccessibleContextFromSource(aEvent.Source); - g_return_if_fail( xParent.is() ); - - if( aEvent.OldValue >>= xChild ) - handleChildRemoved(xParent, xChild); - - if( aEvent.NewValue >>= xChild ) - handleChildAdded(xParent, xChild); - break; - } - - case accessibility::AccessibleEventId::INVALIDATE_ALL_CHILDREN: - { - uno::Reference< accessibility::XAccessibleContext > xParent = getAccessibleContextFromSource(aEvent.Source); - g_return_if_fail( xParent.is() ); - - handleInvalidateChildren(xParent); - break; - } - - case accessibility::AccessibleEventId::NAME_CHANGED: - { - OUString aName; - if( aEvent.NewValue >>= aName ) - { - atk_object_set_name(atk_obj, - OUStringToOString(aName, RTL_TEXTENCODING_UTF8).getStr()); - } - break; - } - - case accessibility::AccessibleEventId::DESCRIPTION_CHANGED: - { - OUString aDescription; - if( aEvent.NewValue >>= aDescription ) - { - atk_object_set_description(atk_obj, - OUStringToOString(aDescription, RTL_TEXTENCODING_UTF8).getStr()); - } - break; - } - - case accessibility::AccessibleEventId::STATE_CHANGED: - { - AtkStateType eOldState = mapState( aEvent.OldValue ); - AtkStateType eNewState = mapState( aEvent.NewValue ); - - gboolean bState = eNewState != ATK_STATE_INVALID; - AtkStateType eRealState = bState ? eNewState : eOldState; - - atk_object_notify_state_change( atk_obj, eRealState, bState ); - break; - } - - case accessibility::AccessibleEventId::BOUNDRECT_CHANGED: - -#ifdef HAS_ATKRECTANGLE - if( ATK_IS_COMPONENT( atk_obj ) ) - { - AtkRectangle rect; - - atk_component_get_extents( ATK_COMPONENT( atk_obj ), - &rect.x, - &rect.y, - &rect.width, - &rect.height, - ATK_XY_SCREEN ); - - g_signal_emit_by_name( atk_obj, "bounds_changed", &rect ); - } - else - g_warning( "bounds_changed event for object not implementing AtkComponent\n"); -#endif - - break; - - case accessibility::AccessibleEventId::VISIBLE_DATA_CHANGED: - g_signal_emit_by_name( atk_obj, "visible-data-changed" ); - break; - - case accessibility::AccessibleEventId::ACTIVE_DESCENDANT_CHANGED: - { - AtkObject *pChild = getObjFromAny( aEvent.NewValue ); - if( pChild ) - { - g_signal_emit_by_name( atk_obj, "active-descendant-changed", pChild ); - g_object_unref( pChild ); - } - break; - } - - //ACTIVE_DESCENDANT_CHANGED_NOFOCUS (sic) appears to have been added - //as a workaround or an aid for the ia2 winaccessibility implementation - //so ignore it silently without warning here - case accessibility::AccessibleEventId::ACTIVE_DESCENDANT_CHANGED_NOFOCUS: - break; - - // #i92103# - case accessibility::AccessibleEventId::LISTBOX_ENTRY_EXPANDED: - { - AtkObject *pChild = getObjFromAny( aEvent.NewValue ); - if( pChild ) - { - atk_object_notify_state_change( pChild, ATK_STATE_EXPANDED, true ); - g_object_unref( pChild ); - } - break; - } - - case accessibility::AccessibleEventId::LISTBOX_ENTRY_COLLAPSED: - { - AtkObject *pChild = getObjFromAny( aEvent.NewValue ); - if( pChild ) - { - atk_object_notify_state_change( pChild, ATK_STATE_EXPANDED, false ); - g_object_unref( pChild ); - } - break; - } - - // AtkAction signals ... - case accessibility::AccessibleEventId::ACTION_CHANGED: - g_signal_emit_by_name( G_OBJECT( atk_obj ), "property_change::accessible-actions"); - break; - - // AtkText - case accessibility::AccessibleEventId::CARET_CHANGED: - { - sal_Int32 nPos=0; - aEvent.NewValue >>= nPos; - g_signal_emit_by_name( atk_obj, "text_caret_moved", nPos ); - break; - } - case accessibility::AccessibleEventId::TEXT_CHANGED: - { - // TESTME: and remove this comment: - // cf. comphelper/source/misc/accessibletexthelper.cxx (implInitTextChangedEvent) - accessibility::TextSegment aDeletedText; - accessibility::TextSegment aInsertedText; - - // TODO: when GNOME starts to send "update" kind of events, change - // we need to re-think this implementation as well - if( aEvent.OldValue >>= aDeletedText ) - { - /* Remember the text segment here to be able to return removed text in get_text(). - * This is clearly a hack to be used until appropriate API exists in atk to pass - * the string value directly or we find a compelling reason to start caching the - * UTF-8 converted strings in the atk wrapper object. - */ - - g_object_set_data( G_OBJECT(atk_obj), "ooo::text_changed::delete", &aDeletedText); - - g_signal_emit_by_name( atk_obj, "text_changed::delete", - static_cast<gint>(aDeletedText.SegmentStart), - static_cast<gint>( aDeletedText.SegmentEnd - aDeletedText.SegmentStart ) ); - - g_object_steal_data( G_OBJECT(atk_obj), "ooo::text_changed::delete" ); - } - - if( aEvent.NewValue >>= aInsertedText ) - g_signal_emit_by_name( atk_obj, "text_changed::insert", - static_cast<gint>(aInsertedText.SegmentStart), - static_cast<gint>( aInsertedText.SegmentEnd - aInsertedText.SegmentStart ) ); - break; - } - - case accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED: - { - g_signal_emit_by_name( atk_obj, "text-selection-changed" ); - break; - } - - case accessibility::AccessibleEventId::TEXT_ATTRIBUTE_CHANGED: - g_signal_emit_by_name( atk_obj, "text-attributes-changed" ); - break; - - // AtkValue - case accessibility::AccessibleEventId::VALUE_CHANGED: - g_object_notify( G_OBJECT( atk_obj ), "accessible-value" ); - break; - - case accessibility::AccessibleEventId::CONTENT_FLOWS_FROM_RELATION_CHANGED: - case accessibility::AccessibleEventId::CONTENT_FLOWS_TO_RELATION_CHANGED: - case accessibility::AccessibleEventId::CONTROLLED_BY_RELATION_CHANGED: - case accessibility::AccessibleEventId::CONTROLLER_FOR_RELATION_CHANGED: - case accessibility::AccessibleEventId::LABEL_FOR_RELATION_CHANGED: - case accessibility::AccessibleEventId::LABELED_BY_RELATION_CHANGED: - case accessibility::AccessibleEventId::MEMBER_OF_RELATION_CHANGED: - case accessibility::AccessibleEventId::SUB_WINDOW_OF_RELATION_CHANGED: - // FIXME: ask Bill how Atk copes with this little lot ... - break; - - // AtkTable - case accessibility::AccessibleEventId::TABLE_MODEL_CHANGED: - { - accessibility::AccessibleTableModelChange aChange; - aEvent.NewValue >>= aChange; - - sal_Int32 nRowsChanged = aChange.LastRow - aChange.FirstRow + 1; - sal_Int32 nColumnsChanged = aChange.LastColumn - aChange.FirstColumn + 1; - - static const struct { - const char *row; - const char *col; - } aSignalNames[] = - { - { nullptr, nullptr }, // dummy - { "row_inserted", "column_inserted" }, // INSERT = 1 - { "row_deleted", "column_deleted" } // DELETE = 2 - }; - switch( aChange.Type ) - { - case accessibility::AccessibleTableModelChangeType::INSERT: - case accessibility::AccessibleTableModelChangeType::DELETE: - if( nRowsChanged > 0 ) - g_signal_emit_by_name( G_OBJECT( atk_obj ), - aSignalNames[aChange.Type].row, - aChange.FirstRow, nRowsChanged ); - if( nColumnsChanged > 0 ) - g_signal_emit_by_name( G_OBJECT( atk_obj ), - aSignalNames[aChange.Type].col, - aChange.FirstColumn, nColumnsChanged ); - break; - - case accessibility::AccessibleTableModelChangeType::UPDATE: - // This is not really a model change, is it ? - break; - default: - g_warning( "TESTME: unusual table model change %d\n", aChange.Type ); - break; - } - g_signal_emit_by_name( G_OBJECT( atk_obj ), "model-changed" ); - break; - } - - case accessibility::AccessibleEventId::TABLE_COLUMN_HEADER_CHANGED: - { - accessibility::AccessibleTableModelChange aChange; - aEvent.NewValue >>= aChange; - - AtkPropertyValues values; - memset(&values, 0, sizeof(AtkPropertyValues)); - g_value_init (&values.new_value, G_TYPE_INT); - values.property_name = "accessible-table-column-header"; - - for (sal_Int32 nChangedColumn = aChange.FirstColumn; nChangedColumn <= aChange.LastColumn; ++nChangedColumn) - { - g_value_set_int (&values.new_value, nChangedColumn); - g_signal_emit_by_name(G_OBJECT(atk_obj), "property_change::accessible-table-column-header", &values, nullptr); - } - break; - } - - case accessibility::AccessibleEventId::TABLE_CAPTION_CHANGED: - g_signal_emit_by_name( G_OBJECT( atk_obj ), "property_change::accessible-table-caption"); - break; - - case accessibility::AccessibleEventId::TABLE_COLUMN_DESCRIPTION_CHANGED: - g_signal_emit_by_name( G_OBJECT( atk_obj ), "property_change::accessible-table-column-description"); - break; - - case accessibility::AccessibleEventId::TABLE_ROW_DESCRIPTION_CHANGED: - g_signal_emit_by_name( G_OBJECT( atk_obj ), "property_change::accessible-table-row-description"); - break; - - case accessibility::AccessibleEventId::TABLE_ROW_HEADER_CHANGED: - g_signal_emit_by_name( G_OBJECT( atk_obj ), "property_change::accessible-table-row-header"); - break; - - case accessibility::AccessibleEventId::TABLE_SUMMARY_CHANGED: - g_signal_emit_by_name( G_OBJECT( atk_obj ), "property_change::accessible-table-summary"); - break; - - case accessibility::AccessibleEventId::SELECTION_CHANGED: - case accessibility::AccessibleEventId::SELECTION_CHANGED_ADD: - case accessibility::AccessibleEventId::SELECTION_CHANGED_REMOVE: - case accessibility::AccessibleEventId::SELECTION_CHANGED_WITHIN: - if (ATK_IS_SELECTION(atk_obj)) - g_signal_emit_by_name(G_OBJECT(atk_obj), "selection_changed"); - else - { - // e.g. tdf#122353, when such dialogs become native the problem will go away anyway - SAL_INFO("vcl.gtk", "selection change from obj which doesn't support XAccessibleSelection"); - } - break; - - case accessibility::AccessibleEventId::HYPERTEXT_CHANGED: - g_signal_emit_by_name( G_OBJECT( atk_obj ), "property_change::accessible-hypertext-offset"); - break; - - case accessibility::AccessibleEventId::ROLE_CHANGED: - { - uno::Reference< accessibility::XAccessibleContext > xContext = getAccessibleContextFromSource( aEvent.Source ); - atk_object_wrapper_set_role( mpWrapper, xContext->getAccessibleRole() ); - break; - } - - case accessibility::AccessibleEventId::PAGE_CHANGED: - { - /* // If we implemented AtkDocument then I imagine this is what this - // handler should look like - sal_Int32 nPos=0; - aEvent.NewValue >>= nPos; - g_signal_emit_by_name( G_OBJECT( atk_obj ), "page_changed", nPos ); - */ - break; - } - - default: - SAL_WARN("vcl.gtk", "Unknown event notification: " << aEvent.EventId); - break; - } -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/a11y/atkregistry.cxx b/vcl/unx/gtk/a11y/atkregistry.cxx deleted file mode 100644 index ff96378c41dc..000000000000 --- a/vcl/unx/gtk/a11y/atkregistry.cxx +++ /dev/null @@ -1,66 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "atkregistry.hxx" - -using namespace ::com::sun::star::accessibility; -using namespace ::com::sun::star::uno; - -static GHashTable *uno_to_gobject = nullptr; - -/*****************************************************************************/ - -AtkObject * -ooo_wrapper_registry_get(const Reference< XAccessible >& rxAccessible) -{ - if( uno_to_gobject ) - { - gpointer cached = - g_hash_table_lookup(uno_to_gobject, static_cast<gpointer>(rxAccessible.get())); - - if( cached ) - return ATK_OBJECT( cached ); - } - - return nullptr; -} - -/*****************************************************************************/ - -void -ooo_wrapper_registry_add(const Reference< XAccessible >& rxAccessible, AtkObject *obj) -{ - if( !uno_to_gobject ) - uno_to_gobject = g_hash_table_new (nullptr, nullptr); - - g_hash_table_insert( uno_to_gobject, static_cast<gpointer>(rxAccessible.get()), obj ); -} - -/*****************************************************************************/ - -void -ooo_wrapper_registry_remove( - css::uno::Reference<css::accessibility::XAccessible> const & pAccessible) -{ - if( uno_to_gobject ) - g_hash_table_remove( - uno_to_gobject, static_cast<gpointer>(pAccessible.get()) ); -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/a11y/atkselection.cxx b/vcl/unx/gtk/a11y/atkselection.cxx deleted file mode 100644 index 1d9772bc1587..000000000000 --- a/vcl/unx/gtk/a11y/atkselection.cxx +++ /dev/null @@ -1,190 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "atkwrapper.hxx" - -#include <com/sun/star/accessibility/XAccessibleSelection.hpp> - -using namespace ::com::sun::star; - -/// @throws uno::RuntimeException -static css::uno::Reference<css::accessibility::XAccessibleSelection> - getSelection( AtkSelection *pSelection ) -{ - AtkObjectWrapper *pWrap = ATK_OBJECT_WRAPPER( pSelection ); - if( pWrap ) - { - if( !pWrap->mpSelection.is() ) - { - pWrap->mpSelection.set(pWrap->mpContext, css::uno::UNO_QUERY); - } - - return pWrap->mpSelection; - } - - return css::uno::Reference<css::accessibility::XAccessibleSelection>(); -} - -extern "C" { - -static gboolean -selection_add_selection( AtkSelection *selection, - gint i ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleSelection> pSelection - = getSelection( selection ); - if( pSelection.is() ) - { - pSelection->selectAccessibleChild( i ); - return TRUE; - } - } - catch(const uno::Exception&) { - g_warning( "Exception in selectAccessibleChild()" ); - } - - return FALSE; -} - -static gboolean -selection_clear_selection( AtkSelection *selection ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleSelection> pSelection - = getSelection( selection ); - if( pSelection.is() ) - { - pSelection->clearAccessibleSelection(); - return TRUE; - } - } - catch(const uno::Exception&) { - g_warning( "Exception in selectAccessibleChild()" ); - } - - return FALSE; -} - -static AtkObject* -selection_ref_selection( AtkSelection *selection, - gint i ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleSelection> pSelection - = getSelection( selection ); - if( pSelection.is() ) - return atk_object_wrapper_ref( pSelection->getSelectedAccessibleChild( i ) ); - } - catch(const uno::Exception&) { - g_warning( "Exception in getSelectedAccessibleChild()" ); - } - - return nullptr; -} - -static gint -selection_get_selection_count( AtkSelection *selection) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleSelection> pSelection - = getSelection( selection ); - if( pSelection.is() ) - return pSelection->getSelectedAccessibleChildCount(); - } - catch(const uno::Exception&) { - g_warning( "Exception in getSelectedAccessibleChildCount()" ); - } - - return -1; -} - -static gboolean -selection_is_child_selected( AtkSelection *selection, - gint i) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleSelection> pSelection - = getSelection( selection ); - if( pSelection.is() ) - return pSelection->isAccessibleChildSelected( i ); - } - catch(const uno::Exception&) { - g_warning( "Exception in getSelectedAccessibleChildCount()" ); - } - - return FALSE; -} - -static gboolean -selection_remove_selection( AtkSelection *selection, - gint i ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleSelection> pSelection - = getSelection( selection ); - if( pSelection.is() ) - { - pSelection->deselectAccessibleChild( i ); - return TRUE; - } - } - catch(const uno::Exception&) { - g_warning( "Exception in getSelectedAccessibleChildCount()" ); - } - - return FALSE; -} - -static gboolean -selection_select_all_selection( AtkSelection *selection) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleSelection> pSelection - = getSelection( selection ); - if( pSelection.is() ) - { - pSelection->selectAllAccessibleChildren(); - return TRUE; - } - } - catch(const uno::Exception&) { - g_warning( "Exception in getSelectedAccessibleChildCount()" ); - } - - return FALSE; -} - -} // extern "C" - -void -selectionIfaceInit( AtkSelectionIface *iface) -{ - g_return_if_fail (iface != nullptr); - - iface->add_selection = selection_add_selection; - iface->clear_selection = selection_clear_selection; - iface->ref_selection = selection_ref_selection; - iface->get_selection_count = selection_get_selection_count; - iface->is_child_selected = selection_is_child_selected; - iface->remove_selection = selection_remove_selection; - iface->select_all_selection = selection_select_all_selection; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/a11y/atktable.cxx b/vcl/unx/gtk/a11y/atktable.cxx deleted file mode 100644 index 221e55d2b287..000000000000 --- a/vcl/unx/gtk/a11y/atktable.cxx +++ /dev/null @@ -1,580 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "atkwrapper.hxx" - -#include <com/sun/star/accessibility/XAccessibleTable.hpp> -#include <comphelper/sequence.hxx> - -using namespace ::com::sun::star; - -static AtkObject * -atk_object_wrapper_conditional_ref( const uno::Reference< accessibility::XAccessible >& rxAccessible ) -{ - if( rxAccessible.is() ) - return atk_object_wrapper_ref( rxAccessible ); - - return nullptr; -} - -/*****************************************************************************/ - -// FIXME -static const gchar * -getAsConst( const OUString& rString ) -{ - static const int nMax = 10; - static OString aUgly[nMax]; - static int nIdx = 0; - nIdx = (nIdx + 1) % nMax; - aUgly[nIdx] = OUStringToOString( rString, RTL_TEXTENCODING_UTF8 ); - return aUgly[ nIdx ].getStr(); -} - -/*****************************************************************************/ - -/// @throws uno::RuntimeException -static css::uno::Reference<css::accessibility::XAccessibleTable> - getTable( AtkTable *pTable ) -{ - AtkObjectWrapper *pWrap = ATK_OBJECT_WRAPPER( pTable ); - if( pWrap ) - { - if( !pWrap->mpTable.is() ) - { - pWrap->mpTable.set(pWrap->mpContext, css::uno::UNO_QUERY); - } - - return pWrap->mpTable; - } - - return css::uno::Reference<css::accessibility::XAccessibleTable>(); -} - -/*****************************************************************************/ - -extern "C" { - -static AtkObject* -table_wrapper_ref_at (AtkTable *table, - gint row, - gint column) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleTable> pTable = getTable( table ); - if( pTable.is() ) - return atk_object_wrapper_conditional_ref( pTable->getAccessibleCellAt( row, column ) ); - } - - catch(const uno::Exception&) { - g_warning( "Exception in getAccessibleCellAt()" ); - } - - return nullptr; -} - -/*****************************************************************************/ - -static gint -table_wrapper_get_index_at (AtkTable *table, - gint row, - gint column) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleTable> pTable - = getTable( table ); - if( pTable.is() ) - return pTable->getAccessibleIndex( row, column ); - } - catch(const uno::Exception&) { - g_warning( "Exception in getAccessibleIndex()" ); - } - - return -1; -} - -/*****************************************************************************/ - -static gint -table_wrapper_get_column_at_index (AtkTable *table, - gint nIndex) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleTable> pTable - = getTable( table ); - if( pTable.is() ) - return pTable->getAccessibleColumn( nIndex ); - } - catch(const uno::Exception&) { - g_warning( "Exception in getAccessibleColumn()" ); - } - - return -1; -} - -/*****************************************************************************/ - -static gint -table_wrapper_get_row_at_index( AtkTable *table, - gint nIndex ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleTable> pTable - = getTable( table ); - if( pTable.is() ) - return pTable->getAccessibleRow( nIndex ); - } - catch(const uno::Exception&) { - g_warning( "Exception in getAccessibleRow()" ); - } - - return -1; -} - -/*****************************************************************************/ - -static gint -table_wrapper_get_n_columns( AtkTable *table ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleTable> pTable - = getTable( table ); - if( pTable.is() ) - return pTable->getAccessibleColumnCount(); - } - catch(const uno::Exception&) { - g_warning( "Exception in getAccessibleColumnCount()" ); - } - - return -1; -} - -/*****************************************************************************/ - -static gint -table_wrapper_get_n_rows( AtkTable *table ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleTable> pTable - = getTable( table ); - if( pTable.is() ) - return pTable->getAccessibleRowCount(); - } - catch(const uno::Exception&) { - g_warning( "Exception in getAccessibleRowCount()" ); - } - - return -1; -} - -/*****************************************************************************/ - -static gint -table_wrapper_get_column_extent_at( AtkTable *table, - gint row, - gint column ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleTable> pTable - = getTable( table ); - if( pTable.is() ) - return pTable->getAccessibleColumnExtentAt( row, column ); - } - catch(const uno::Exception&) { - g_warning( "Exception in getAccessibleColumnExtentAt()" ); - } - - return -1; -} - -/*****************************************************************************/ - -static gint -table_wrapper_get_row_extent_at( AtkTable *table, - gint row, - gint column ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleTable> pTable - = getTable( table ); - if( pTable.is() ) - return pTable->getAccessibleRowExtentAt( row, column ); - } - catch(const uno::Exception&) { - g_warning( "Exception in getAccessibleRowExtentAt()" ); - } - - return -1; -} - -/*****************************************************************************/ - -static AtkObject * -table_wrapper_get_caption( AtkTable *table ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleTable> pTable - = getTable( table ); - if( pTable.is() ) - return atk_object_wrapper_conditional_ref( pTable->getAccessibleCaption() ); - } - - catch(const uno::Exception&) { - g_warning( "Exception in getAccessibleCaption()" ); - } - - return nullptr; -} - -/*****************************************************************************/ - -static const gchar * -table_wrapper_get_row_description( AtkTable *table, - gint row ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleTable> pTable - = getTable( table ); - if( pTable.is() ) - return getAsConst( pTable->getAccessibleRowDescription( row ) ); - } - catch(const uno::Exception&) { - g_warning( "Exception in getAccessibleRowDescription()" ); - } - - return nullptr; -} - -/*****************************************************************************/ - -static const gchar * -table_wrapper_get_column_description( AtkTable *table, - gint column ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleTable> pTable - = getTable( table ); - if( pTable.is() ) - return getAsConst( pTable->getAccessibleColumnDescription( column ) ); - } - catch(const uno::Exception&) { - g_warning( "Exception in getAccessibleColumnDescription()" ); - } - - return nullptr; -} - -/*****************************************************************************/ - -static AtkObject * -table_wrapper_get_row_header( AtkTable *table, - gint row ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleTable> pTable - = getTable( table ); - if( pTable.is() ) - { - uno::Reference< accessibility::XAccessibleTable > xRowHeaders( pTable->getAccessibleRowHeaders() ); - if( xRowHeaders.is() ) - return atk_object_wrapper_conditional_ref( xRowHeaders->getAccessibleCellAt( row, 0 ) ); - } - } - catch(const uno::Exception&) { - g_warning( "Exception in getAccessibleRowHeaders()" ); - } - - return nullptr; -} - -/*****************************************************************************/ - -static AtkObject * -table_wrapper_get_column_header( AtkTable *table, - gint column ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleTable> pTable - = getTable( table ); - if( pTable.is() ) - { - uno::Reference< accessibility::XAccessibleTable > xColumnHeaders( pTable->getAccessibleColumnHeaders() ); - if( xColumnHeaders.is() ) - return atk_object_wrapper_conditional_ref( xColumnHeaders->getAccessibleCellAt( 0, column ) ); - } - } - catch(const uno::Exception&) { - g_warning( "Exception in getAccessibleColumnHeaders()" ); - } - - return nullptr; -} - -/*****************************************************************************/ - -static AtkObject * -table_wrapper_get_summary( AtkTable *table ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleTable> pTable - = getTable( table ); - if( pTable.is() ) - { - return atk_object_wrapper_conditional_ref( pTable->getAccessibleSummary() ); - } - } - catch(const uno::Exception&) { - g_warning( "Exception in getAccessibleSummary()" ); - } - - return nullptr; -} - -/*****************************************************************************/ - -static gint -convertToGIntArray( const uno::Sequence< ::sal_Int32 >& aSequence, gint **pSelected ) -{ - if( aSequence.hasElements() ) - { - *pSelected = g_new( gint, aSequence.getLength() ); - - *pSelected = comphelper::sequenceToArray(*pSelected, aSequence); - } - - return aSequence.getLength(); -} - -/*****************************************************************************/ - -static gint -table_wrapper_get_selected_columns( AtkTable *table, - gint **pSelected ) -{ - *pSelected = nullptr; - try { - css::uno::Reference<css::accessibility::XAccessibleTable> pTable - = getTable( table ); - if( pTable.is() ) - return convertToGIntArray( pTable->getSelectedAccessibleColumns(), pSelected ); - } - catch(const uno::Exception&) { - g_warning( "Exception in getSelectedAccessibleColumns()" ); - } - - return 0; -} - -/*****************************************************************************/ - -static gint -table_wrapper_get_selected_rows( AtkTable *table, - gint **pSelected ) -{ - *pSelected = nullptr; - try { - css::uno::Reference<css::accessibility::XAccessibleTable> pTable - = getTable( table ); - if( pTable.is() ) - return convertToGIntArray( pTable->getSelectedAccessibleRows(), pSelected ); - } - catch(const uno::Exception&) { - g_warning( "Exception in getSelectedAccessibleRows()" ); - } - - return 0; -} - -/*****************************************************************************/ - -static gboolean -table_wrapper_is_column_selected( AtkTable *table, - gint column ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleTable> pTable - = getTable( table ); - if( pTable.is() ) - return pTable->isAccessibleColumnSelected( column ); - } - catch(const uno::Exception&) { - g_warning( "Exception in isAccessibleColumnSelected()" ); - } - - return 0; -} - -/*****************************************************************************/ - -static gboolean -table_wrapper_is_row_selected( AtkTable *table, - gint row ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleTable> pTable - = getTable( table ); - if( pTable.is() ) - return pTable->isAccessibleRowSelected( row ); - } - catch(const uno::Exception&) { - g_warning( "Exception in isAccessibleRowSelected()" ); - } - - return FALSE; -} - -/*****************************************************************************/ - -static gboolean -table_wrapper_is_selected( AtkTable *table, - gint row, - gint column ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleTable> pTable - = getTable( table ); - if( pTable.is() ) - return pTable->isAccessibleSelected( row, column ); - } - catch(const uno::Exception&) { - g_warning( "Exception in isAccessibleSelected()" ); - } - - return FALSE; -} - -/*****************************************************************************/ - -static gboolean -table_wrapper_add_row_selection( AtkTable *, gint ) -{ - g_warning( "FIXME: no simple analogue for add_row_selection" ); - return 0; -} - -/*****************************************************************************/ - -static gboolean -table_wrapper_remove_row_selection( AtkTable *, gint ) -{ - g_warning( "FIXME: no simple analogue for remove_row_selection" ); - return 0; -} - -/*****************************************************************************/ - -static gboolean -table_wrapper_add_column_selection( AtkTable *, gint ) -{ - g_warning( "FIXME: no simple analogue for add_column_selection" ); - return 0; -} - -/*****************************************************************************/ - -static gboolean -table_wrapper_remove_column_selection( AtkTable *, gint ) -{ - g_warning( "FIXME: no simple analogue for remove_column_selection" ); - return 0; -} - -/*****************************************************************************/ - -static void -table_wrapper_set_caption( AtkTable *, AtkObject * ) -{ // meaningless helper -} - -/*****************************************************************************/ - -static void -table_wrapper_set_column_description( AtkTable *, gint, const gchar * ) -{ // meaningless helper -} - -/*****************************************************************************/ - -static void -table_wrapper_set_column_header( AtkTable *, gint, AtkObject * ) -{ // meaningless helper -} - -/*****************************************************************************/ - -static void -table_wrapper_set_row_description( AtkTable *, gint, const gchar * ) -{ // meaningless helper -} - -/*****************************************************************************/ - -static void -table_wrapper_set_row_header( AtkTable *, gint, AtkObject * ) -{ // meaningless helper -} - -/*****************************************************************************/ - -static void -table_wrapper_set_summary( AtkTable *, AtkObject * ) -{ // meaningless helper -} - -/*****************************************************************************/ - -} // extern "C" - -void -tableIfaceInit (AtkTableIface *iface) -{ - g_return_if_fail (iface != nullptr); - - iface->ref_at = table_wrapper_ref_at; - iface->get_n_rows = table_wrapper_get_n_rows; - iface->get_n_columns = table_wrapper_get_n_columns; - iface->get_index_at = table_wrapper_get_index_at; - iface->get_column_at_index = table_wrapper_get_column_at_index; - iface->get_row_at_index = table_wrapper_get_row_at_index; - iface->is_row_selected = table_wrapper_is_row_selected; - iface->is_selected = table_wrapper_is_selected; - iface->get_selected_rows = table_wrapper_get_selected_rows; - iface->add_row_selection = table_wrapper_add_row_selection; - iface->remove_row_selection = table_wrapper_remove_row_selection; - iface->add_column_selection = table_wrapper_add_column_selection; - iface->remove_column_selection = table_wrapper_remove_column_selection; - iface->get_selected_columns = table_wrapper_get_selected_columns; - iface->is_column_selected = table_wrapper_is_column_selected; - iface->get_column_extent_at = table_wrapper_get_column_extent_at; - iface->get_row_extent_at = table_wrapper_get_row_extent_at; - iface->get_row_header = table_wrapper_get_row_header; - iface->set_row_header = table_wrapper_set_row_header; - iface->get_column_header = table_wrapper_get_column_header; - iface->set_column_header = table_wrapper_set_column_header; - iface->get_caption = table_wrapper_get_caption; - iface->set_caption = table_wrapper_set_caption; - iface->get_summary = table_wrapper_get_summary; - iface->set_summary = table_wrapper_set_summary; - iface->get_row_description = table_wrapper_get_row_description; - iface->set_row_description = table_wrapper_set_row_description; - iface->get_column_description = table_wrapper_get_column_description; - iface->set_column_description = table_wrapper_set_column_description; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/a11y/atktext.cxx b/vcl/unx/gtk/a11y/atktext.cxx deleted file mode 100644 index 1406ceea5544..000000000000 --- a/vcl/unx/gtk/a11y/atktext.cxx +++ /dev/null @@ -1,838 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "atkwrapper.hxx" -#include "atktextattributes.hxx" -#include <algorithm> - -#include <osl/diagnose.h> - -#include <com/sun/star/accessibility/AccessibleTextType.hpp> -#include <com/sun/star/accessibility/TextSegment.hpp> -#include <com/sun/star/accessibility/XAccessibleMultiLineText.hpp> -#include <com/sun/star/accessibility/XAccessibleText.hpp> -#include <com/sun/star/accessibility/XAccessibleTextAttributes.hpp> -#include <com/sun/star/accessibility/XAccessibleTextMarkup.hpp> -#include <com/sun/star/text/TextMarkupType.hpp> - -using namespace ::com::sun::star; - -static sal_Int16 -text_type_from_boundary(AtkTextBoundary boundary_type) -{ - switch(boundary_type) - { - case ATK_TEXT_BOUNDARY_CHAR: - return accessibility::AccessibleTextType::CHARACTER; - case ATK_TEXT_BOUNDARY_WORD_START: - case ATK_TEXT_BOUNDARY_WORD_END: - return accessibility::AccessibleTextType::WORD; - case ATK_TEXT_BOUNDARY_SENTENCE_START: - case ATK_TEXT_BOUNDARY_SENTENCE_END: - return accessibility::AccessibleTextType::SENTENCE; - case ATK_TEXT_BOUNDARY_LINE_START: - case ATK_TEXT_BOUNDARY_LINE_END: - return accessibility::AccessibleTextType::LINE; - default: - return -1; - } -} - -/*****************************************************************************/ - -static gchar * -adjust_boundaries( css::uno::Reference<css::accessibility::XAccessibleText> const & pText, - accessibility::TextSegment const & rTextSegment, - AtkTextBoundary boundary_type, - gint * start_offset, gint * end_offset ) -{ - accessibility::TextSegment aTextSegment; - OUString aString; - gint start = 0, end = 0; - - if( !rTextSegment.SegmentText.isEmpty() ) - { - switch(boundary_type) - { - case ATK_TEXT_BOUNDARY_CHAR: - case ATK_TEXT_BOUNDARY_LINE_START: - case ATK_TEXT_BOUNDARY_LINE_END: - case ATK_TEXT_BOUNDARY_SENTENCE_START: - start = rTextSegment.SegmentStart; - end = rTextSegment.SegmentEnd; - aString = rTextSegment.SegmentText; - break; - - // the OOo break iterator behaves as SENTENCE_START - case ATK_TEXT_BOUNDARY_SENTENCE_END: - start = rTextSegment.SegmentStart; - end = rTextSegment.SegmentEnd; - - if( start > 0 ) - --start; - if( end > 0 && end < pText->getCharacterCount() - 1 ) - --end; - - aString = pText->getTextRange(start, end); - break; - - case ATK_TEXT_BOUNDARY_WORD_START: - start = rTextSegment.SegmentStart; - - // Determine the start index of the next segment - aTextSegment = pText->getTextBehindIndex(rTextSegment.SegmentEnd, - text_type_from_boundary(boundary_type)); - if( !aTextSegment.SegmentText.isEmpty() ) - end = aTextSegment.SegmentStart; - else - end = pText->getCharacterCount(); - - aString = pText->getTextRange(start, end); - break; - - case ATK_TEXT_BOUNDARY_WORD_END: - end = rTextSegment.SegmentEnd; - - // Determine the end index of the previous segment - aTextSegment = pText->getTextBeforeIndex(rTextSegment.SegmentStart, - text_type_from_boundary(boundary_type)); - if( !aTextSegment.SegmentText.isEmpty() ) - start = aTextSegment.SegmentEnd; - else - start = 0; - - aString = pText->getTextRange(start, end); - break; - - default: - return nullptr; - } - } - - *start_offset = start; - *end_offset = end; - - return OUStringToGChar(aString); -} - -/*****************************************************************************/ - -/// @throws uno::RuntimeException -static css::uno::Reference<css::accessibility::XAccessibleText> - getText( AtkText *pText ) -{ - AtkObjectWrapper *pWrap = ATK_OBJECT_WRAPPER( pText ); - if( pWrap ) - { - if( !pWrap->mpText.is() ) - { - pWrap->mpText.set(pWrap->mpContext, css::uno::UNO_QUERY); - } - - return pWrap->mpText; - } - - return css::uno::Reference<css::accessibility::XAccessibleText>(); -} - -/*****************************************************************************/ - -/// @throws uno::RuntimeException -static css::uno::Reference<css::accessibility::XAccessibleTextMarkup> - getTextMarkup( AtkText *pText ) -{ - AtkObjectWrapper *pWrap = ATK_OBJECT_WRAPPER( pText ); - if( pWrap ) - { - if( !pWrap->mpTextMarkup.is() ) - { - pWrap->mpTextMarkup.set(pWrap->mpContext, css::uno::UNO_QUERY); - } - - return pWrap->mpTextMarkup; - } - - return css::uno::Reference<css::accessibility::XAccessibleTextMarkup>(); -} - -/*****************************************************************************/ - -/// @throws uno::RuntimeException -static css::uno::Reference<css::accessibility::XAccessibleTextAttributes> - getTextAttributes( AtkText *pText ) -{ - AtkObjectWrapper *pWrap = ATK_OBJECT_WRAPPER( pText ); - if( pWrap ) - { - if( !pWrap->mpTextAttributes.is() ) - { - pWrap->mpTextAttributes.set(pWrap->mpContext, css::uno::UNO_QUERY); - } - - return pWrap->mpTextAttributes; - } - - return css::uno::Reference<css::accessibility::XAccessibleTextAttributes>(); -} - -/*****************************************************************************/ - -/// @throws uno::RuntimeException -static css::uno::Reference<css::accessibility::XAccessibleMultiLineText> - getMultiLineText( AtkText *pText ) -{ - AtkObjectWrapper *pWrap = ATK_OBJECT_WRAPPER( pText ); - if( pWrap ) - { - if( !pWrap->mpMultiLineText.is() ) - { - pWrap->mpMultiLineText.set(pWrap->mpContext, css::uno::UNO_QUERY); - } - - return pWrap->mpMultiLineText; - } - - return css::uno::Reference<css::accessibility::XAccessibleMultiLineText>(); -} - -/*****************************************************************************/ - -extern "C" { - -static gchar * -text_wrapper_get_text (AtkText *text, - gint start_offset, - gint end_offset) -{ - gchar * ret = nullptr; - - g_return_val_if_fail( (end_offset == -1) || (end_offset >= start_offset), nullptr ); - - /* at-spi expects the delete event to be send before the deletion happened - * so we save the deleted string object in the UNO event notification and - * fool libatk-bridge.so here .. - */ - void * pData = g_object_get_data( G_OBJECT(text), "ooo::text_changed::delete" ); - if( pData != nullptr ) - { - accessibility::TextSegment * pTextSegment = - static_cast <accessibility::TextSegment *> (pData); - - if( pTextSegment->SegmentStart == start_offset && - pTextSegment->SegmentEnd == end_offset ) - { - OString aUtf8 = OUStringToOString( pTextSegment->SegmentText, RTL_TEXTENCODING_UTF8 ); - return g_strdup( aUtf8.getStr() ); - } - } - - try { - css::uno::Reference<css::accessibility::XAccessibleText> pText - = getText( text ); - if( pText.is() ) - { - OUString aText; - sal_Int32 n = pText->getCharacterCount(); - - if( -1 == end_offset ) - aText = pText->getText(); - else if( start_offset < n ) - aText = pText->getTextRange(start_offset, end_offset); - - ret = g_strdup( OUStringToOString(aText, RTL_TEXTENCODING_UTF8 ).getStr() ); - } - } - catch(const uno::Exception&) { - g_warning( "Exception in getText()" ); - } - - return ret; -} - -static gchar * -text_wrapper_get_text_after_offset (AtkText *text, - gint offset, - AtkTextBoundary boundary_type, - gint *start_offset, - gint *end_offset) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleText> pText - = getText( text ); - if( pText.is() ) - { - accessibility::TextSegment aTextSegment = pText->getTextBehindIndex(offset, text_type_from_boundary(boundary_type)); - return adjust_boundaries(pText, aTextSegment, boundary_type, start_offset, end_offset); - } - } - catch(const uno::Exception&) { - g_warning( "Exception in get_text_after_offset()" ); - } - - return nullptr; -} - -static gchar * -text_wrapper_get_text_at_offset (AtkText *text, - gint offset, - AtkTextBoundary boundary_type, - gint *start_offset, - gint *end_offset) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleText> pText - = getText( text ); - if( pText.is() ) - { - /* If the user presses the 'End' key, the caret will be placed behind the last character, - * which is the same index as the first character of the next line. In atk the magic offset - * '-2' is used to cover this special case. - */ - if ( - -2 == offset && - (ATK_TEXT_BOUNDARY_LINE_START == boundary_type || - ATK_TEXT_BOUNDARY_LINE_END == boundary_type) - ) - { - css::uno::Reference< - css::accessibility::XAccessibleMultiLineText> pMultiLineText - = getMultiLineText( text ); - if( pMultiLineText.is() ) - { - accessibility::TextSegment aTextSegment = pMultiLineText->getTextAtLineWithCaret(); - return adjust_boundaries(pText, aTextSegment, boundary_type, start_offset, end_offset); - } - } - - accessibility::TextSegment aTextSegment = pText->getTextAtIndex(offset, text_type_from_boundary(boundary_type)); - return adjust_boundaries(pText, aTextSegment, boundary_type, start_offset, end_offset); - } - } - catch(const uno::Exception&) { - g_warning( "Exception in get_text_at_offset()" ); - } - - return nullptr; -} - -static gunichar -text_wrapper_get_character_at_offset (AtkText *text, - gint offset) -{ - gint start, end; - gunichar uc = 0; - - gchar * char_as_string = - text_wrapper_get_text_at_offset(text, offset, ATK_TEXT_BOUNDARY_CHAR, - &start, &end); - if( char_as_string ) - { - uc = g_utf8_get_char( char_as_string ); - g_free( char_as_string ); - } - - return uc; -} - -static gchar * -text_wrapper_get_text_before_offset (AtkText *text, - gint offset, - AtkTextBoundary boundary_type, - gint *start_offset, - gint *end_offset) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleText> pText - = getText( text ); - if( pText.is() ) - { - accessibility::TextSegment aTextSegment = pText->getTextBeforeIndex(offset, text_type_from_boundary(boundary_type)); - return adjust_boundaries(pText, aTextSegment, boundary_type, start_offset, end_offset); - } - } - catch(const uno::Exception&) { - g_warning( "Exception in text_before_offset()" ); - } - - return nullptr; -} - -static gint -text_wrapper_get_caret_offset (AtkText *text) -{ - gint offset = -1; - - try { - css::uno::Reference<css::accessibility::XAccessibleText> pText - = getText( text ); - if( pText.is() ) - offset = pText->getCaretPosition(); - } - catch(const uno::Exception&) { - g_warning( "Exception in getCaretPosition()" ); - } - - return offset; -} - -static gboolean -text_wrapper_set_caret_offset (AtkText *text, - gint offset) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleText> pText - = getText( text ); - if( pText.is() ) - return pText->setCaretPosition( offset ); - } - catch(const uno::Exception&) { - g_warning( "Exception in setCaretPosition()" ); - } - - return FALSE; -} - -// #i92232# -static AtkAttributeSet* -handle_text_markup_as_run_attribute( css::uno::Reference<css::accessibility::XAccessibleTextMarkup> const & pTextMarkup, - const gint nTextMarkupType, - const gint offset, - AtkAttributeSet* pSet, - gint *start_offset, - gint *end_offset ) -{ - const gint nTextMarkupCount( pTextMarkup->getTextMarkupCount( nTextMarkupType ) ); - if ( nTextMarkupCount > 0 ) - { - for ( gint nTextMarkupIndex = 0; - nTextMarkupIndex < nTextMarkupCount; - ++nTextMarkupIndex ) - { - accessibility::TextSegment aTextSegment = - pTextMarkup->getTextMarkup( nTextMarkupIndex, nTextMarkupType ); - const gint nStartOffsetTextMarkup = aTextSegment.SegmentStart; - const gint nEndOffsetTextMarkup = aTextSegment.SegmentEnd; - if ( nStartOffsetTextMarkup <= offset ) - { - if ( offset < nEndOffsetTextMarkup ) - { - // text markup at <offset> - *start_offset = ::std::max( *start_offset, - nStartOffsetTextMarkup ); - *end_offset = ::std::min( *end_offset, - nEndOffsetTextMarkup ); - switch ( nTextMarkupType ) - { - case css::text::TextMarkupType::SPELLCHECK: - { - pSet = attribute_set_prepend_misspelled( pSet ); - } - break; - case css::text::TextMarkupType::TRACK_CHANGE_INSERTION: - { - pSet = attribute_set_prepend_tracked_change_insertion( pSet ); - } - break; - case css::text::TextMarkupType::TRACK_CHANGE_DELETION: - { - pSet = attribute_set_prepend_tracked_change_deletion( pSet ); - } - break; - case css::text::TextMarkupType::TRACK_CHANGE_FORMATCHANGE: - { - pSet = attribute_set_prepend_tracked_change_formatchange( pSet ); - } - break; - default: - { - OSL_ASSERT( false ); - } - } - break; // no further iteration needed. - } - else - { - *start_offset = ::std::max( *start_offset, - nEndOffsetTextMarkup ); - // continue iteration. - } - } - else - { - *end_offset = ::std::min( *end_offset, - nStartOffsetTextMarkup ); - break; // no further iteration. - } - } // eof iteration over text markups - } - - return pSet; -} - -static AtkAttributeSet * -text_wrapper_get_run_attributes( AtkText *text, - gint offset, - gint *start_offset, - gint *end_offset) -{ - AtkAttributeSet *pSet = nullptr; - - try { - bool bOffsetsAreValid = false; - - css::uno::Reference<css::accessibility::XAccessibleText> pText - = getText( text ); - if( pText.is()) - { - uno::Sequence< beans::PropertyValue > aAttributeList; - - css::uno::Reference<css::accessibility::XAccessibleTextAttributes> - pTextAttributes = getTextAttributes( text ); - if(pTextAttributes.is()) // Text attributes are available for paragraphs only - { - aAttributeList = pTextAttributes->getRunAttributes( offset, uno::Sequence< OUString > () ); - } - else // For other text objects use character attributes - { - aAttributeList = pText->getCharacterAttributes( offset, uno::Sequence< OUString > () ); - } - - pSet = attribute_set_new_from_property_values( aAttributeList, true, text ); - // #i100938# - // - always provide start_offset and end_offset - { - accessibility::TextSegment aTextSegment = - pText->getTextAtIndex(offset, accessibility::AccessibleTextType::ATTRIBUTE_RUN); - - *start_offset = aTextSegment.SegmentStart; - // #i100938# - // Do _not_ increment the end_offset provide by <accessibility::TextSegment> instance - *end_offset = aTextSegment.SegmentEnd; - bOffsetsAreValid = true; - } - } - - // Special handling for misspelled text - // #i92232# - // - add special handling for tracked changes and refactor the - // corresponding code for handling misspelled text. - css::uno::Reference<css::accessibility::XAccessibleTextMarkup> - pTextMarkup = getTextMarkup( text ); - if( pTextMarkup.is() ) - { - // Get attribute run here if it hasn't been done before - if (!bOffsetsAreValid && pText.is()) - { - accessibility::TextSegment aAttributeTextSegment = - pText->getTextAtIndex(offset, accessibility::AccessibleTextType::ATTRIBUTE_RUN); - *start_offset = aAttributeTextSegment.SegmentStart; - *end_offset = aAttributeTextSegment.SegmentEnd; - } - // handle misspelled text - pSet = handle_text_markup_as_run_attribute( - pTextMarkup, - css::text::TextMarkupType::SPELLCHECK, - offset, pSet, start_offset, end_offset ); - // handle tracked changes - pSet = handle_text_markup_as_run_attribute( - pTextMarkup, - css::text::TextMarkupType::TRACK_CHANGE_INSERTION, - offset, pSet, start_offset, end_offset ); - pSet = handle_text_markup_as_run_attribute( - pTextMarkup, - css::text::TextMarkupType::TRACK_CHANGE_DELETION, - offset, pSet, start_offset, end_offset ); - pSet = handle_text_markup_as_run_attribute( - pTextMarkup, - css::text::TextMarkupType::TRACK_CHANGE_FORMATCHANGE, - offset, pSet, start_offset, end_offset ); - } - } - catch(const uno::Exception&){ - - g_warning( "Exception in get_run_attributes()" ); - - if( pSet ) - { - atk_attribute_set_free( pSet ); - pSet = nullptr; - } - } - - return pSet; -} - -/*****************************************************************************/ - -static AtkAttributeSet * -text_wrapper_get_default_attributes( AtkText *text ) -{ - AtkAttributeSet *pSet = nullptr; - - try { - css::uno::Reference<css::accessibility::XAccessibleTextAttributes> - pTextAttributes = getTextAttributes( text ); - if( pTextAttributes.is() ) - { - uno::Sequence< beans::PropertyValue > aAttributeList = - pTextAttributes->getDefaultAttributes( uno::Sequence< OUString > () ); - - pSet = attribute_set_new_from_property_values( aAttributeList, false, text ); - } - } - catch(const uno::Exception&) { - - g_warning( "Exception in get_default_attributes()" ); - - if( pSet ) - { - atk_attribute_set_free( pSet ); - pSet = nullptr; - } - } - - return pSet; -} - -/*****************************************************************************/ - -static void -text_wrapper_get_character_extents( AtkText *text, - gint offset, - gint *x, - gint *y, - gint *width, - gint *height, - AtkCoordType coords ) -{ - *x = *y = *width = *height = -1; - - try { - css::uno::Reference<css::accessibility::XAccessibleText> pText - = getText( text ); - if( pText.is() ) - { - awt::Rectangle aRect = pText->getCharacterBounds( offset ); - - gint origin_x = 0; - gint origin_y = 0; - - if( coords == ATK_XY_SCREEN ) - { - g_return_if_fail( ATK_IS_COMPONENT( text ) ); - SAL_WNODEPRECATED_DECLARATIONS_PUSH - atk_component_get_position( ATK_COMPONENT( text ), &origin_x, &origin_y, coords); - SAL_WNODEPRECATED_DECLARATIONS_POP - } - - *x = aRect.X + origin_x; - *y = aRect.Y + origin_y; - *width = aRect.Width; - *height = aRect.Height; - } - } - catch(const uno::Exception&) { - g_warning( "Exception in getCharacterBounds" ); - } -} - -static gint -text_wrapper_get_character_count (AtkText *text) -{ - gint rv = 0; - - try { - css::uno::Reference<css::accessibility::XAccessibleText> pText - = getText( text ); - if( pText.is() ) - rv = pText->getCharacterCount(); - } - catch(const uno::Exception&) { - g_warning( "Exception in getCharacterCount" ); - } - - return rv; -} - -static gint -text_wrapper_get_offset_at_point (AtkText *text, - gint x, - gint y, - AtkCoordType coords) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleText> pText - = getText( text ); - if( pText.is() ) - { - gint origin_x = 0; - gint origin_y = 0; - - if( coords == ATK_XY_SCREEN ) - { - g_return_val_if_fail( ATK_IS_COMPONENT( text ), -1 ); - SAL_WNODEPRECATED_DECLARATIONS_PUSH - atk_component_get_position( ATK_COMPONENT( text ), &origin_x, &origin_y, coords); - SAL_WNODEPRECATED_DECLARATIONS_POP - } - - return pText->getIndexAtPoint( awt::Point(x - origin_x, y - origin_y) ); - } - } - catch(const uno::Exception&) { - g_warning( "Exception in getIndexAtPoint" ); - } - - return -1; -} - -// FIXME: the whole series of selections API is problematic ... - -static gint -text_wrapper_get_n_selections (AtkText *text) -{ - gint rv = 0; - - try { - css::uno::Reference<css::accessibility::XAccessibleText> pText - = getText( text ); - if( pText.is() ) - rv = ( pText->getSelectionEnd() > pText->getSelectionStart() ) ? 1 : 0; - } - catch(const uno::Exception&) { - g_warning( "Exception in getSelectionEnd() or getSelectionStart()" ); - } - - return rv; -} - -static gchar * -text_wrapper_get_selection (AtkText *text, - gint selection_num, - gint *start_offset, - gint *end_offset) -{ - g_return_val_if_fail( selection_num == 0, FALSE ); - - try { - css::uno::Reference<css::accessibility::XAccessibleText> pText - = getText( text ); - if( pText.is() ) - { - *start_offset = pText->getSelectionStart(); - *end_offset = pText->getSelectionEnd(); - - return OUStringToGChar( pText->getSelectedText() ); - } - } - catch(const uno::Exception&) { - g_warning( "Exception in getSelectionEnd(), getSelectionStart() or getSelectedText()" ); - } - - return nullptr; -} - -static gboolean -text_wrapper_add_selection (AtkText *text, - gint start_offset, - gint end_offset) -{ - // FIXME: can we try to be more compatible by expanding an - // existing adjacent selection ? - - try { - css::uno::Reference<css::accessibility::XAccessibleText> pText - = getText( text ); - if( pText.is() ) - return pText->setSelection( start_offset, end_offset ); // ? - } - catch(const uno::Exception&) { - g_warning( "Exception in setSelection()" ); - } - - return FALSE; -} - -static gboolean -text_wrapper_remove_selection (AtkText *text, - gint selection_num) -{ - g_return_val_if_fail( selection_num == 0, FALSE ); - - try { - css::uno::Reference<css::accessibility::XAccessibleText> pText - = getText( text ); - if( pText.is() ) - return pText->setSelection( 0, 0 ); // ? - } - catch(const uno::Exception&) { - g_warning( "Exception in setSelection()" ); - } - - return FALSE; -} - -static gboolean -text_wrapper_set_selection (AtkText *text, - gint selection_num, - gint start_offset, - gint end_offset) -{ - g_return_val_if_fail( selection_num == 0, FALSE ); - - try { - css::uno::Reference<css::accessibility::XAccessibleText> pText - = getText( text ); - if( pText.is() ) - return pText->setSelection( start_offset, end_offset ); - } - catch(const uno::Exception&) { - g_warning( "Exception in setSelection()" ); - } - - return FALSE; -} - -} // extern "C" - -void -textIfaceInit (AtkTextIface *iface) -{ - g_return_if_fail (iface != nullptr); - - iface->get_text = text_wrapper_get_text; - iface->get_character_at_offset = text_wrapper_get_character_at_offset; - iface->get_text_before_offset = text_wrapper_get_text_before_offset; - iface->get_text_at_offset = text_wrapper_get_text_at_offset; - iface->get_text_after_offset = text_wrapper_get_text_after_offset; - iface->get_caret_offset = text_wrapper_get_caret_offset; - iface->set_caret_offset = text_wrapper_set_caret_offset; - iface->get_character_count = text_wrapper_get_character_count; - iface->get_n_selections = text_wrapper_get_n_selections; - iface->get_selection = text_wrapper_get_selection; - iface->add_selection = text_wrapper_add_selection; - iface->remove_selection = text_wrapper_remove_selection; - iface->set_selection = text_wrapper_set_selection; - iface->get_run_attributes = text_wrapper_get_run_attributes; - iface->get_default_attributes = text_wrapper_get_default_attributes; - iface->get_character_extents = text_wrapper_get_character_extents; - iface->get_offset_at_point = text_wrapper_get_offset_at_point; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/a11y/atktextattributes.cxx b/vcl/unx/gtk/a11y/atktextattributes.cxx deleted file mode 100644 index 0ba7fd561862..000000000000 --- a/vcl/unx/gtk/a11y/atktextattributes.cxx +++ /dev/null @@ -1,1383 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "atktextattributes.hxx" - -#include <com/sun/star/awt/FontSlant.hpp> -#include <com/sun/star/awt/FontStrikeout.hpp> -#include <com/sun/star/awt/FontUnderline.hpp> - -#include <com/sun/star/style/CaseMap.hpp> -#include <com/sun/star/style/LineSpacing.hpp> -#include <com/sun/star/style/LineSpacingMode.hpp> -#include <com/sun/star/style/ParagraphAdjust.hpp> -#include <com/sun/star/style/TabAlign.hpp> -#include <com/sun/star/style/TabStop.hpp> - -#include <com/sun/star/text/WritingMode2.hpp> - -#include "atkwrapper.hxx" - -#include <com/sun/star/accessibility/XAccessibleComponent.hpp> - -#include <i18nlangtag/languagetag.hxx> -#include <vcl/svapp.hxx> -#include <vcl/outdev.hxx> - -#include <stdio.h> -#include <string.h> - -using namespace ::com::sun::star; - -typedef gchar* (* AtkTextAttrFunc) ( const uno::Any& rAny ); -typedef bool (* TextPropertyValueFunc) ( uno::Any& rAny, const gchar * value ); - -#define STRNCMP_PARAM( s ) s,sizeof( s )-1 - -/*****************************************************************************/ - -static AtkTextAttribute atk_text_attribute_paragraph_style = ATK_TEXT_ATTR_INVALID; -static AtkTextAttribute atk_text_attribute_font_effect = ATK_TEXT_ATTR_INVALID; -static AtkTextAttribute atk_text_attribute_decoration = ATK_TEXT_ATTR_INVALID; -static AtkTextAttribute atk_text_attribute_line_height = ATK_TEXT_ATTR_INVALID; -static AtkTextAttribute atk_text_attribute_rotation = ATK_TEXT_ATTR_INVALID; -static AtkTextAttribute atk_text_attribute_shadow = ATK_TEXT_ATTR_INVALID; -static AtkTextAttribute atk_text_attribute_tab_interval = ATK_TEXT_ATTR_INVALID; -static AtkTextAttribute atk_text_attribute_tab_stops = ATK_TEXT_ATTR_INVALID; -static AtkTextAttribute atk_text_attribute_writing_mode = ATK_TEXT_ATTR_INVALID; -static AtkTextAttribute atk_text_attribute_vertical_align = ATK_TEXT_ATTR_INVALID; -static AtkTextAttribute atk_text_attribute_misspelled = ATK_TEXT_ATTR_INVALID; -// #i92232# -static AtkTextAttribute atk_text_attribute_tracked_change = ATK_TEXT_ATTR_INVALID; -// #i92233# -static AtkTextAttribute atk_text_attribute_mm_to_pixel_ratio = ATK_TEXT_ATTR_INVALID; - -/*****************************************************************************/ - -/** - * !! IMPORTANT NOTE !! : when adding items to this list, KEEP THE LIST SORTED - * and re-arrange the enum values accordingly. - */ - -enum ExportedAttribute -{ - TEXT_ATTRIBUTE_BACKGROUND_COLOR = 0, - TEXT_ATTRIBUTE_CASEMAP, - TEXT_ATTRIBUTE_FOREGROUND_COLOR, - TEXT_ATTRIBUTE_CONTOURED, - TEXT_ATTRIBUTE_CHAR_ESCAPEMENT, - TEXT_ATTRIBUTE_BLINKING, - TEXT_ATTRIBUTE_FONT_NAME, - TEXT_ATTRIBUTE_HEIGHT, - TEXT_ATTRIBUTE_HIDDEN, - TEXT_ATTRIBUTE_KERNING, - TEXT_ATTRIBUTE_LOCALE, - TEXT_ATTRIBUTE_POSTURE, - TEXT_ATTRIBUTE_RELIEF, - TEXT_ATTRIBUTE_ROTATION, - TEXT_ATTRIBUTE_SCALE, - TEXT_ATTRIBUTE_SHADOWED, - TEXT_ATTRIBUTE_STRIKETHROUGH, - TEXT_ATTRIBUTE_UNDERLINE, - TEXT_ATTRIBUTE_WEIGHT, - // #i92233# - TEXT_ATTRIBUTE_MM_TO_PIXEL_RATIO, - TEXT_ATTRIBUTE_JUSTIFICATION, - TEXT_ATTRIBUTE_BOTTOM_MARGIN, - TEXT_ATTRIBUTE_FIRST_LINE_INDENT, - TEXT_ATTRIBUTE_LEFT_MARGIN, - TEXT_ATTRIBUTE_LINE_SPACING, - TEXT_ATTRIBUTE_RIGHT_MARGIN, - TEXT_ATTRIBUTE_STYLE_NAME, - TEXT_ATTRIBUTE_TAB_STOPS, - TEXT_ATTRIBUTE_TOP_MARGIN, - TEXT_ATTRIBUTE_WRITING_MODE, - TEXT_ATTRIBUTE_LAST -}; - -static const char * ExportedTextAttributes[TEXT_ATTRIBUTE_LAST] = -{ - "CharBackColor", // TEXT_ATTRIBUTE_BACKGROUND_COLOR - "CharCaseMap", // TEXT_ATTRIBUTE_CASEMAP - "CharColor", // TEXT_ATTRIBUTE_FOREGROUND_COLOR - "CharContoured", // TEXT_ATTRIBUTE_CONTOURED - "CharEscapement", // TEXT_ATTRIBUTE_CHAR_ESCAPEMENT - "CharFlash", // TEXT_ATTRIBUTE_BLINKING - "CharFontName", // TEXT_ATTRIBUTE_FONT_NAME - "CharHeight", // TEXT_ATTRIBUTE_HEIGHT - "CharHidden", // TEXT_ATTRIBUTE_HIDDEN - "CharKerning", // TEXT_ATTRIBUTE_KERNING - "CharLocale", // TEXT_ATTRIBUTE_LOCALE - "CharPosture", // TEXT_ATTRIBUTE_POSTURE - "CharRelief", // TEXT_ATTRIBUTE_RELIEF - "CharRotation", // TEXT_ATTRIBUTE_ROTATION - "CharScaleWidth", // TEXT_ATTRIBUTE_SCALE - "CharShadowed", // TEXT_ATTRIBUTE_SHADOWED - "CharStrikeout", // TEXT_ATTRIBUTE_STRIKETHROUGH - "CharUnderline", // TEXT_ATTRIBUTE_UNDERLINE - "CharWeight", // TEXT_ATTRIBUTE_WEIGHT - // #i92233# - "MMToPixelRatio", // TEXT_ATTRIBUTE_MM_TO_PIXEL_RATIO - "ParaAdjust", // TEXT_ATTRIBUTE_JUSTIFICATION - "ParaBottomMargin", // TEXT_ATTRIBUTE_BOTTOM_MARGIN - "ParaFirstLineIndent", // TEXT_ATTRIBUTE_FIRST_LINE_INDENT - "ParaLeftMargin", // TEXT_ATTRIBUTE_LEFT_MARGIN - "ParaLineSpacing", // TEXT_ATTRIBUTE_LINE_SPACING - "ParaRightMargin", // TEXT_ATTRIBUTE_RIGHT_MARGIN - "ParaStyleName", // TEXT_ATTRIBUTE_STYLE_NAME - "ParaTabStops", // TEXT_ATTRIBUTE_TAB_STOPS - "ParaTopMargin", // TEXT_ATTRIBUTE_TOP_MARGIN - "WritingMode" // TEXT_ATTRIBUTE_WRITING_MODE -}; - -/*****************************************************************************/ - -static gchar* -get_value( const uno::Sequence< beans::PropertyValue >& rAttributeList, - sal_Int32 nIndex, AtkTextAttrFunc func ) -{ - if( nIndex != -1 ) - return func(rAttributeList[nIndex].Value); - - return nullptr; -} - -#define get_bool_value( list, index ) get_value( list, index, Bool2String ) -#define get_height_value( list, index ) get_value( list, index, Float2String ) -#define get_justification_value( list, index ) get_value( list, index, Adjust2Justification ) -#define get_cmm_value( list, index ) get_value( list, index, CMM2UnitString ) -#define get_scale_width( list, index ) get_value( list, index, Scale2String ) -#define get_strikethrough_value( list, index ) get_value( list, index, Strikeout2String ) -#define get_string_value( list, index ) get_value( list, index, GetString ) -#define get_style_value( list, index ) get_value( list, index, FontSlant2Style ) -#define get_underline_value( list, index ) get_value( list, index, Underline2String ) -#define get_variant_value( list, index ) get_value( list, index, CaseMap2String ) -#define get_weight_value( list, index ) get_value( list, index, Weight2String ) -#define get_language_string( list, index ) get_value( list, index, Locale2String ) - -static double toPoint(sal_Int16 n) -{ - // 100th mm -> pt - return static_cast<double>(n * 72) / 2540; -} - -/*****************************************************************************/ - -static bool -InvalidValue( uno::Any&, const gchar * ) -{ - return false; -} - -/*****************************************************************************/ - -static gchar* -Float2String(const uno::Any& rAny) -{ - return g_strdup_printf( "%g", rAny.get<float>() ); -} - -static bool -String2Float( uno::Any& rAny, const gchar * value ) -{ - float fval; - - if( 1 != sscanf( value, "%g", &fval ) ) - return false; - - rAny <<= fval; - return true; -} - -/*****************************************************************************/ - -/// @throws uno::RuntimeException -static css::uno::Reference<css::accessibility::XAccessibleComponent> - getComponent( AtkText *pText ) -{ - AtkObjectWrapper *pWrap = ATK_OBJECT_WRAPPER( pText ); - if( pWrap ) - { - if( !pWrap->mpComponent.is() ) - { - pWrap->mpComponent.set(pWrap->mpContext, css::uno::UNO_QUERY); - } - - return pWrap->mpComponent; - } - - return css::uno::Reference<css::accessibility::XAccessibleComponent>(); -} - -static gchar* -get_color_value(const uno::Sequence< beans::PropertyValue >& rAttributeList, - const sal_Int32 * pIndexArray, - ExportedAttribute attr, - AtkText * text) -{ - sal_Int32 nColor = -1; // AUTOMATIC - sal_Int32 nIndex = pIndexArray[attr]; - - if( nIndex != -1 ) - nColor = rAttributeList[nIndex].Value.get<sal_Int32>(); - - /* - * Check for color value for 100% alpha white, which means - * "automatic". Grab the RGB value from XAccessibleComponent - * in this case. - */ - - if( (nColor == -1) && text ) - { - try - { - css::uno::Reference<css::accessibility::XAccessibleComponent> - pComponent = getComponent( text ); - if( pComponent.is() ) - { - switch( attr ) - { - case TEXT_ATTRIBUTE_BACKGROUND_COLOR: - nColor = pComponent->getBackground(); - break; - case TEXT_ATTRIBUTE_FOREGROUND_COLOR: - nColor = pComponent->getForeground(); - break; - default: - break; - } - } - } - - catch(const uno::Exception&) { - g_warning( "Exception in get[Fore|Back]groundColor()" ); - } - } - - if( nColor != -1 ) - { - sal_uInt8 blue = nColor & 0xFF; - sal_uInt8 green = (nColor >> 8) & 0xFF; - sal_uInt8 red = (nColor >> 16) & 0xFF; - - return g_strdup_printf( "%u,%u,%u", red, green, blue ); - } - - return nullptr; -} - -static bool -String2Color( uno::Any& rAny, const gchar * value ) -{ - int red, green, blue; - - if( 3 != sscanf( value, "%d,%d,%d", &red, &green, &blue ) ) - return false; - - sal_Int32 nColor = static_cast<sal_Int32>(blue) | ( static_cast<sal_Int32>(green) << 8 ) | ( static_cast<sal_Int32>(red) << 16 ); - rAny <<= nColor; - return true; -} - -/*****************************************************************************/ - -static gchar* -FontSlant2Style(const uno::Any& rAny) -{ - const gchar * value = nullptr; - - awt::FontSlant aFontSlant; - if(!(rAny >>= aFontSlant)) - return nullptr; - - switch( aFontSlant ) - { - case awt::FontSlant_NONE: - value = "normal"; - break; - - case awt::FontSlant_OBLIQUE: - value = "oblique"; - break; - - case awt::FontSlant_ITALIC: - value = "italic"; - break; - - case awt::FontSlant_REVERSE_OBLIQUE: - value = "reverse oblique"; - break; - - case awt::FontSlant_REVERSE_ITALIC: - value = "reverse italic"; - break; - - default: - break; - } - - if( value ) - return g_strdup( value ); - - return nullptr; -} - -static bool -Style2FontSlant( uno::Any& rAny, const gchar * value ) -{ - awt::FontSlant aFontSlant; - - if( strncmp( value, STRNCMP_PARAM( "normal" ) ) == 0 ) - aFontSlant = awt::FontSlant_NONE; - else if( strncmp( value, STRNCMP_PARAM( "oblique" ) ) == 0 ) - aFontSlant = awt::FontSlant_OBLIQUE; - else if( strncmp( value, STRNCMP_PARAM( "italic" ) ) == 0 ) - aFontSlant = awt::FontSlant_ITALIC; - else if( strncmp( value, STRNCMP_PARAM( "reverse oblique" ) ) == 0 ) - aFontSlant = awt::FontSlant_REVERSE_OBLIQUE; - else if( strncmp( value, STRNCMP_PARAM( "reverse italic" ) ) == 0 ) - aFontSlant = awt::FontSlant_REVERSE_ITALIC; - else - return false; - - rAny <<= aFontSlant; - return true; -} - -/*****************************************************************************/ - -static gchar* -Weight2String(const uno::Any& rAny) -{ - return g_strdup_printf( "%g", rAny.get<float>() * 4 ); -} - -static bool -String2Weight( uno::Any& rAny, const gchar * value ) -{ - float weight; - - if( 1 != sscanf( value, "%g", &weight ) ) - return false; - - rAny <<= weight / 4; - return true; -} - -/*****************************************************************************/ - -static gchar* -Adjust2Justification(const uno::Any& rAny) -{ - const gchar * value = nullptr; - - switch( static_cast<style::ParagraphAdjust>(rAny.get<short>()) ) - { - case style::ParagraphAdjust_LEFT: - value = "left"; - break; - - case style::ParagraphAdjust_RIGHT: - value = "right"; - break; - - case style::ParagraphAdjust_BLOCK: - case style::ParagraphAdjust_STRETCH: - value = "fill"; - break; - - case style::ParagraphAdjust_CENTER: - value = "center"; - break; - - default: - break; - } - - if( value ) - return g_strdup( value ); - - return nullptr; -} - -static bool -Justification2Adjust( uno::Any& rAny, const gchar * value ) -{ - style::ParagraphAdjust nParagraphAdjust; - - if( strncmp( value, STRNCMP_PARAM( "left" ) ) == 0 ) - nParagraphAdjust = style::ParagraphAdjust_LEFT; - else if( strncmp( value, STRNCMP_PARAM( "right" ) ) == 0 ) - nParagraphAdjust = style::ParagraphAdjust_RIGHT; - else if( strncmp( value, STRNCMP_PARAM( "fill" ) ) == 0 ) - nParagraphAdjust = style::ParagraphAdjust_BLOCK; - else if( strncmp( value, STRNCMP_PARAM( "center" ) ) == 0 ) - nParagraphAdjust = style::ParagraphAdjust_CENTER; - else - return false; - - rAny <<= static_cast<short>(nParagraphAdjust); - return true; -} - -/*****************************************************************************/ - -const gchar * const font_strikethrough[] = { - "none", // FontStrikeout::NONE - "single", // FontStrikeout::SINGLE - "double", // FontStrikeout::DOUBLE - nullptr, // FontStrikeout::DONTKNOW - "bold", // FontStrikeout::BOLD - "with /", // FontStrikeout::SLASH - "with X" // FontStrikeout::X -}; - -static gchar* -Strikeout2String(const uno::Any& rAny) -{ - sal_Int16 n = rAny.get<sal_Int16>(); - - if( n >= 0 && n < sal_Int16(SAL_N_ELEMENTS(font_strikethrough)) ) - return g_strdup( font_strikethrough[n] ); - - return nullptr; -} - -static bool -String2Strikeout( uno::Any& rAny, const gchar * value ) -{ - for( sal_Int16 n=0; n < sal_Int16(SAL_N_ELEMENTS(font_strikethrough)); ++n ) - { - if( ( nullptr != font_strikethrough[n] ) && - 0 == strncmp( value, font_strikethrough[n], strlen( font_strikethrough[n] ) ) ) - { - rAny <<= n; - return true; - } - } - - return false; -} - -/*****************************************************************************/ - -static gchar* -Underline2String(const uno::Any& rAny) -{ - const gchar * value = nullptr; - - switch( rAny.get<sal_Int16>() ) - { - case awt::FontUnderline::NONE: - value = "none"; - break; - - case awt::FontUnderline::SINGLE: - value = "single"; - break; - - case awt::FontUnderline::DOUBLE: - value = "double"; - break; - - default: - break; - } - - if( value ) - return g_strdup( value ); - - return nullptr; -} - -static bool -String2Underline( uno::Any& rAny, const gchar * value ) -{ - short nUnderline; - - if( strncmp( value, STRNCMP_PARAM( "none" ) ) == 0 ) - nUnderline = awt::FontUnderline::NONE; - else if( strncmp( value, STRNCMP_PARAM( "single" ) ) == 0 ) - nUnderline = awt::FontUnderline::SINGLE; - else if( strncmp( value, STRNCMP_PARAM( "double" ) ) == 0 ) - nUnderline = awt::FontUnderline::DOUBLE; - else - return false; - - rAny <<= nUnderline; - return true; -} - -/*****************************************************************************/ - -static gchar* -GetString(const uno::Any& rAny) -{ - OString aFontName = OUStringToOString( rAny.get< OUString > (), RTL_TEXTENCODING_UTF8 ); - - if( !aFontName.isEmpty() ) - return g_strdup( aFontName.getStr() ); - - return nullptr; -} - -static bool -SetString( uno::Any& rAny, const gchar * value ) -{ - OString aFontName( value ); - - if( !aFontName.isEmpty() ) - { - rAny <<= OStringToOUString( aFontName, RTL_TEXTENCODING_UTF8 ); - return true; - } - - return false; -} - -/*****************************************************************************/ - -// @see http://developer.gnome.org/doc/API/2.0/atk/AtkText.html#AtkTextAttribute - -// CMM = 100th of mm -static gchar* -CMM2UnitString(const uno::Any& rAny) -{ - double fValue = rAny.get<sal_Int32>(); - fValue = fValue * 0.01; - - return g_strdup_printf( "%gmm", fValue ); -} - -static bool -UnitString2CMM( uno::Any& rAny, const gchar * value ) -{ - float fValue = 0.0; // pb: don't use double here because of warning on linux - - if( 1 != sscanf( value, "%gmm", &fValue ) ) - return false; - - fValue = fValue * 100; - - rAny <<= static_cast<sal_Int32>(fValue); - return true; -} - -/*****************************************************************************/ - -static const gchar * bool_values[] = { "true", "false" }; - -static gchar * -Bool2String( const uno::Any& rAny ) -{ - int n = 1; - - if( rAny.get<bool>() ) - n = 0; - - return g_strdup( bool_values[n] ); -} - -static bool -String2Bool( uno::Any& rAny, const gchar * value ) -{ - bool bValue; - - if( strncmp( value, STRNCMP_PARAM( "true" ) ) == 0 ) - bValue = true; - else if( strncmp( value, STRNCMP_PARAM( "false" ) ) == 0 ) - bValue = false; - else - return false; - - rAny <<= bValue; - return true; -} - -/*****************************************************************************/ - -static gchar* -Scale2String( const uno::Any& rAny ) -{ - return g_strdup_printf( "%g", static_cast<double>(rAny.get< sal_Int16 > ()) / 100 ); -} - -static bool -String2Scale( uno::Any& rAny, const gchar * value ) -{ - double dval; - - if( 1 != sscanf( value, "%lg", &dval ) ) - return false; - - rAny <<= static_cast<sal_Int16>(dval * 100); - return true; -} - -/*****************************************************************************/ - -static gchar * -CaseMap2String( const uno::Any& rAny ) -{ - const gchar * value; - - switch( rAny.get<short>() ) - { - case style::CaseMap::SMALLCAPS: - value = "small_caps"; - break; - - default: - value = "normal"; - break; - } - - return g_strdup(value); -} - -static bool -String2CaseMap( uno::Any& rAny, const gchar * value ) -{ - short nCaseMap; - - if( strncmp( value, STRNCMP_PARAM( "normal" ) ) == 0 ) - nCaseMap = style::CaseMap::NONE; - else if( strncmp( value, STRNCMP_PARAM( "small_caps" ) ) == 0 ) - nCaseMap = style::CaseMap::SMALLCAPS; - else - return false; - - rAny <<= nCaseMap; - return true; -} - -/*****************************************************************************/ - -const gchar * const font_stretch[] = { - "ultra_condensed", - "extra_condensed", - "condensed", - "semi_condensed", - "normal", - "semi_expanded", - "expanded", - "extra_expanded", - "ultra_expanded" -}; - -static gchar* -Kerning2Stretch(const uno::Any& rAny) -{ - sal_Int16 n = rAny.get<sal_Int16>(); - int i = 4; - - // No good idea for a mapping - just return the basic info - if( n < 0 ) - i=2; - else if( n > 0 ) - i=6; - - return g_strdup(font_stretch[i]); -} - -/*****************************************************************************/ - -static gchar* -Locale2String(const uno::Any& rAny) -{ - /* FIXME-BCP47: support language tags? And why is country lowercase? */ - lang::Locale aLocale = rAny.get<lang::Locale> (); - LanguageTag aLanguageTag( aLocale); - return g_strdup_printf( "%s-%s", - OUStringToOString( aLanguageTag.getLanguage(), RTL_TEXTENCODING_ASCII_US).getStr(), - OUStringToOString( aLanguageTag.getCountry(), RTL_TEXTENCODING_ASCII_US).toAsciiLowerCase().getStr() ); -} - -static bool -String2Locale( uno::Any& rAny, const gchar * value ) -{ - /* FIXME-BCP47: support language tags? */ - bool ret = false; - - gchar ** str_array = g_strsplit_set( value, "-.@", -1 ); - if( str_array[0] != nullptr ) - { - ret = true; - - lang::Locale aLocale; - - aLocale.Language = OUString::createFromAscii(str_array[0]); - if( str_array[1] != nullptr ) - { - gchar * country = g_ascii_strup(str_array[1], -1); - aLocale.Country = OUString::createFromAscii(country); - g_free(country); - } - - rAny <<= aLocale; - } - - g_strfreev(str_array); - return ret; -} - -/*****************************************************************************/ - -// @see http://www.w3.org/TR/2002/WD-css3-fonts-20020802/#font-effect-prop -static const gchar * relief[] = { "none", "emboss", "engrave" }; -static const gchar * const outline = "outline"; - -static gchar * -get_font_effect(const uno::Sequence< beans::PropertyValue >& rAttributeList, - sal_Int32 nContourIndex, sal_Int32 nReliefIndex) -{ - if( nContourIndex != -1 ) - { - if( rAttributeList[nContourIndex].Value.get<bool>() ) - return g_strdup(outline); - } - - if( nReliefIndex != -1 ) - { - sal_Int16 n = rAttributeList[nReliefIndex].Value.get<sal_Int16>(); - if( n < 3) - return g_strdup(relief[n]); - } - - return nullptr; -} - -/*****************************************************************************/ - -// @see http://www.w3.org/TR/REC-CSS2/text.html#lining-striking-props - -enum -{ - DECORATION_NONE = 0, - DECORATION_BLINK, - DECORATION_UNDERLINE, - DECORATION_LINE_THROUGH -}; - -static const gchar * decorations[] = { "none", "blink", "underline", "line-through" }; - -static gchar * -get_text_decoration(const uno::Sequence< beans::PropertyValue >& rAttributeList, - sal_Int32 nBlinkIndex, sal_Int32 nUnderlineIndex, - sal_Int16 nStrikeoutIndex) -{ - gchar * value_list[4] = { nullptr, nullptr, nullptr, nullptr }; - gint count = 0; - - // no property value found - if( ( nBlinkIndex == -1 ) && (nUnderlineIndex == -1 ) && (nStrikeoutIndex == -1)) - return nullptr; - - if( nBlinkIndex != -1 ) - { - if( rAttributeList[nBlinkIndex].Value.get<bool>() ) - value_list[count++] = const_cast <gchar *> (decorations[DECORATION_BLINK]); - } - if( nUnderlineIndex != -1 ) - { - sal_Int16 n = rAttributeList[nUnderlineIndex].Value.get<sal_Int16> (); - if( n != awt::FontUnderline::NONE ) - value_list[count++] = const_cast <gchar *> (decorations[DECORATION_UNDERLINE]); - } - if( nStrikeoutIndex != -1 ) - { - sal_Int16 n = rAttributeList[nStrikeoutIndex].Value.get<sal_Int16> (); - if( n != awt::FontStrikeout::NONE && n != awt::FontStrikeout::DONTKNOW ) - value_list[count++] = const_cast <gchar *> (decorations[DECORATION_LINE_THROUGH]); - } - - if( count == 0 ) - value_list[count++] = const_cast <gchar *> (decorations[DECORATION_NONE]); - - return g_strjoinv(" ", value_list); -} - -/*****************************************************************************/ - -// @see http://www.w3.org/TR/REC-CSS2/text.html#propdef-text-shadow - -static const gchar * shadow_values[] = { "none", "black" }; - -static gchar * -Bool2Shadow( const uno::Any& rAny ) -{ - int n = 0; - - if( rAny.get<bool>() ) - n = 1; - - return g_strdup( shadow_values[n] ); -} - -/*****************************************************************************/ - -static gchar * -Short2Degree( const uno::Any& rAny ) -{ - float f = rAny.get<sal_Int16>() / 10.0; - return g_strdup_printf( "%g", f ); -} - -/*****************************************************************************/ - -const gchar * const directions[] = { "ltr", "rtl", "rtl", "ltr", "none" }; - -static gchar * -WritingMode2Direction( const uno::Any& rAny ) -{ - sal_Int16 n = rAny.get<sal_Int16>(); - - if( 0 <= n && n <= text::WritingMode2::PAGE ) - return g_strdup(directions[n]); - - return nullptr; -} - -// @see http://www.w3.org/TR/2001/WD-css3-text-20010517/#PrimaryTextAdvanceDirection - -const gchar * const writing_modes[] = { "lr-tb", "rl-tb", "tb-rl", "tb-lr", "none" }; -static gchar * -WritingMode2String( const uno::Any& rAny ) -{ - sal_Int16 n = rAny.get<sal_Int16>(); - - if( 0 <= n && n <= text::WritingMode2::PAGE ) - return g_strdup(writing_modes[n]); - - return nullptr; -} - -/*****************************************************************************/ - -const char * const baseline_values[] = { "baseline", "sub", "super" }; - -// @see http://www.w3.org/TR/REC-CSS2/visudet.html#propdef-vertical-align -static gchar * -Escapement2VerticalAlign( const uno::Any& rAny ) -{ - sal_Int16 n = rAny.get<sal_Int16>(); - gchar * ret = nullptr; - - // Values are in %, 101% means "automatic" - if( n == 0 ) - ret = g_strdup(baseline_values[0]); - else if( n == 101 ) - ret = g_strdup(baseline_values[2]); - else if( n == -101 ) - ret = g_strdup(baseline_values[1]); - else - ret = g_strdup_printf( "%d%%", n ); - - return ret; -} - -/*****************************************************************************/ - -// @see http://www.w3.org/TR/REC-CSS2/visudet.html#propdef-line-height -static gchar * -LineSpacing2LineHeight( const uno::Any& rAny ) -{ - style::LineSpacing ls; - gchar * ret = nullptr; - - if( rAny >>= ls ) - { - if( ls.Mode == style::LineSpacingMode::PROP ) - ret = g_strdup_printf( "%d%%", ls.Height ); - else if( ls.Mode == style::LineSpacingMode::FIX ) - ret = g_strdup_printf( "%.3gpt", toPoint(ls.Height) ); - } - - return ret; -} - -/*****************************************************************************/ - -// @see http://www.w3.org/People/howcome/t/970224HTMLERB-CSS/WD-tabs-970117.html -static gchar * -TabStopList2String( const uno::Any& rAny, bool default_tabs ) -{ - uno::Sequence< style::TabStop > theTabStops; - gchar * ret = nullptr; - - if( rAny >>= theTabStops) - { - sal_Unicode lastFillChar = ' '; - - for( const auto& rTabStop : std::as_const(theTabStops) ) - { - bool is_default_tab = (style::TabAlign_DEFAULT == rTabStop.Alignment); - - if( is_default_tab != default_tabs ) - continue; - - double fValue = rTabStop.Position; - fValue = fValue * 0.01; - - const gchar * tab_align = ""; - switch( rTabStop.Alignment ) - { - case style::TabAlign_LEFT : - tab_align = "left "; - break; - case style::TabAlign_CENTER : - tab_align = "center "; - break; - case style::TabAlign_RIGHT : - tab_align = "right "; - break; - case style::TabAlign_DECIMAL : - tab_align = "decimal "; - break; - default: - break; - } - - const gchar * lead_char = ""; - - if( rTabStop.FillChar != lastFillChar ) - { - lastFillChar = rTabStop.FillChar; - switch (lastFillChar) - { - case ' ': - lead_char = "blank "; - break; - - case '.': - lead_char = "dotted "; - break; - - case '-': - lead_char = "dashed "; - break; - - case '_': - lead_char = "lined "; - break; - - default: - lead_char = "custom "; - break; - } - } - - gchar * tab_str = g_strdup_printf( "%s%s%gmm", lead_char, tab_align, fValue ); - - if( ret ) - { - gchar * old_tab_str = ret; - ret = g_strconcat(old_tab_str, " ", tab_str, nullptr); - g_free( old_tab_str ); - } - else - ret = tab_str; - } - } - - return ret; -} - -static gchar * -TabStops2String( const uno::Any& rAny ) -{ - return TabStopList2String(rAny, false); -} - -static gchar * -DefaultTabStops2String( const uno::Any& rAny ) -{ - return TabStopList2String(rAny, true); -} - -/*****************************************************************************/ - -extern "C" { - -static int -attr_compare(const void *p1,const void *p2) -{ - const rtl_uString * pustr = static_cast<const rtl_uString *>(p1); - const char * pc = *static_cast<const char * const *>(p2); - - return rtl_ustr_ascii_compare_WithLength(pustr->buffer, pustr->length, pc); -} - -} - -static void -find_exported_attributes( sal_Int32 *pArray, - const css::uno::Sequence< css::beans::PropertyValue >& rAttributeList ) -{ - for( sal_Int32 i = 0; i < rAttributeList.getLength(); i++ ) - { - const char ** pAttr = static_cast<const char **>(bsearch(rAttributeList[i].Name.pData, - ExportedTextAttributes, TEXT_ATTRIBUTE_LAST, sizeof(const char *), - attr_compare)); - - if( pAttr ) - { - sal_Int32 nIndex = pAttr - ExportedTextAttributes; - pArray[nIndex] = i; - } - } -} - -/*****************************************************************************/ - -static AtkAttributeSet* -attribute_set_prepend( AtkAttributeSet* attribute_set, - AtkTextAttribute attribute, - gchar * value ) -{ - if( value ) - { - AtkAttribute *at = static_cast<AtkAttribute *>(g_malloc( sizeof (AtkAttribute) )); - at->name = g_strdup( atk_text_attribute_get_name( attribute ) ); - at->value = value; - - return g_slist_prepend(attribute_set, at); - } - - return attribute_set; -} - -/*****************************************************************************/ - -AtkAttributeSet* -attribute_set_new_from_property_values( - const uno::Sequence< beans::PropertyValue >& rAttributeList, - bool run_attributes_only, - AtkText *text) -{ - AtkAttributeSet* attribute_set = nullptr; - - sal_Int32 aIndexList[TEXT_ATTRIBUTE_LAST] = { -1 }; - - // Initialize index array with -1 - for(sal_Int32 & rn : aIndexList) - rn = -1; - - find_exported_attributes(aIndexList, rAttributeList); - - attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_BG_COLOR, - get_color_value(rAttributeList, aIndexList, TEXT_ATTRIBUTE_BACKGROUND_COLOR, run_attributes_only ? nullptr : text ) ); - - attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_FG_COLOR, - get_color_value(rAttributeList, aIndexList, TEXT_ATTRIBUTE_FOREGROUND_COLOR, run_attributes_only ? nullptr : text) ); - - attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_INVISIBLE, - get_bool_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_HIDDEN])); - - attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_UNDERLINE, - get_underline_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_UNDERLINE])); - - attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_STRIKETHROUGH, - get_strikethrough_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_STRIKETHROUGH])); - - attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_SIZE, - get_height_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_HEIGHT])); - - attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_WEIGHT, - get_weight_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_WEIGHT])); - - attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_FAMILY_NAME, - get_string_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_FONT_NAME])); - - attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_VARIANT, - get_variant_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_CASEMAP])); - - attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_STYLE, - get_style_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_POSTURE])); - - attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_SCALE, - get_scale_width(rAttributeList, aIndexList[TEXT_ATTRIBUTE_SCALE])); - - attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_LANGUAGE, - get_language_string(rAttributeList, aIndexList[TEXT_ATTRIBUTE_LOCALE])); - - attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_DIRECTION, - get_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_WRITING_MODE], WritingMode2Direction)); - - attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_STRETCH, - get_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_KERNING], Kerning2Stretch)); - - if( ATK_TEXT_ATTR_INVALID == atk_text_attribute_font_effect ) - atk_text_attribute_font_effect = atk_text_attribute_register("font-effect"); - - attribute_set = attribute_set_prepend(attribute_set, atk_text_attribute_font_effect, - get_font_effect(rAttributeList, aIndexList[TEXT_ATTRIBUTE_CONTOURED], aIndexList[TEXT_ATTRIBUTE_RELIEF])); - - if( ATK_TEXT_ATTR_INVALID == atk_text_attribute_decoration ) - atk_text_attribute_decoration = atk_text_attribute_register("text-decoration"); - - attribute_set = attribute_set_prepend(attribute_set, atk_text_attribute_decoration, - get_text_decoration(rAttributeList, aIndexList[TEXT_ATTRIBUTE_BLINKING], - aIndexList[TEXT_ATTRIBUTE_UNDERLINE], aIndexList[TEXT_ATTRIBUTE_STRIKETHROUGH])); - - if( ATK_TEXT_ATTR_INVALID == atk_text_attribute_rotation ) - atk_text_attribute_rotation = atk_text_attribute_register("text-rotation"); - - attribute_set = attribute_set_prepend(attribute_set, atk_text_attribute_rotation, - get_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_ROTATION], Short2Degree)); - - if( ATK_TEXT_ATTR_INVALID == atk_text_attribute_shadow ) - atk_text_attribute_shadow = atk_text_attribute_register("text-shadow"); - - attribute_set = attribute_set_prepend(attribute_set, atk_text_attribute_shadow, - get_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_SHADOWED], Bool2Shadow)); - - if( ATK_TEXT_ATTR_INVALID == atk_text_attribute_writing_mode ) - atk_text_attribute_writing_mode = atk_text_attribute_register("writing-mode"); - - attribute_set = attribute_set_prepend(attribute_set, atk_text_attribute_writing_mode, - get_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_WRITING_MODE], WritingMode2String)); - - if( ATK_TEXT_ATTR_INVALID == atk_text_attribute_vertical_align ) - atk_text_attribute_vertical_align = atk_text_attribute_register("vertical-align"); - - attribute_set = attribute_set_prepend(attribute_set, atk_text_attribute_vertical_align, - get_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_CHAR_ESCAPEMENT], Escapement2VerticalAlign)); - - if( run_attributes_only ) - return attribute_set; - - attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_LEFT_MARGIN, - get_cmm_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_LEFT_MARGIN])); - - attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_RIGHT_MARGIN, - get_cmm_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_RIGHT_MARGIN])); - - attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_INDENT, - get_cmm_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_FIRST_LINE_INDENT])); - - attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_PIXELS_ABOVE_LINES, - get_cmm_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_TOP_MARGIN])); - - attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_PIXELS_BELOW_LINES, - get_cmm_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_BOTTOM_MARGIN])); - - attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_JUSTIFICATION, - get_justification_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_JUSTIFICATION])); - - if( ATK_TEXT_ATTR_INVALID == atk_text_attribute_paragraph_style ) - atk_text_attribute_paragraph_style = atk_text_attribute_register("paragraph-style"); - - attribute_set = attribute_set_prepend(attribute_set, atk_text_attribute_paragraph_style, - get_string_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_STYLE_NAME])); - - if( ATK_TEXT_ATTR_INVALID == atk_text_attribute_line_height ) - atk_text_attribute_line_height = atk_text_attribute_register("line-height"); - - attribute_set = attribute_set_prepend(attribute_set, atk_text_attribute_line_height, - get_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_LINE_SPACING], LineSpacing2LineHeight)); - - if( ATK_TEXT_ATTR_INVALID == atk_text_attribute_tab_interval ) - atk_text_attribute_tab_interval = atk_text_attribute_register("tab-interval"); - - attribute_set = attribute_set_prepend(attribute_set, atk_text_attribute_tab_interval, - get_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_TAB_STOPS], DefaultTabStops2String)); - - if( ATK_TEXT_ATTR_INVALID == atk_text_attribute_tab_stops ) - atk_text_attribute_tab_stops = atk_text_attribute_register("tab-stops"); - - attribute_set = attribute_set_prepend(attribute_set, atk_text_attribute_tab_stops, - get_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_TAB_STOPS], TabStops2String)); - - // #i92233# - if( ATK_TEXT_ATTR_INVALID == atk_text_attribute_mm_to_pixel_ratio ) - atk_text_attribute_mm_to_pixel_ratio = atk_text_attribute_register("mm-to-pixel-ratio"); - - attribute_set = attribute_set_prepend( attribute_set, atk_text_attribute_mm_to_pixel_ratio, - get_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_MM_TO_PIXEL_RATIO], Float2String)); - - return attribute_set; -} - -AtkAttributeSet* -attribute_set_new_from_extended_attributes( - const css::uno::Reference< css::accessibility::XAccessibleExtendedAttributes >& rExtendedAttributes ) -{ - AtkAttributeSet *pSet = nullptr; - - // extended attributes is a string of colon-separated pairs of property and value, - // with pairs separated by semicolons. Example: "heading-level:2;weight:bold;" - uno::Any anyVal = rExtendedAttributes->getExtendedAttributes(); - OUString sExtendedAttrs; - anyVal >>= sExtendedAttrs; - sal_Int32 nIndex = 0; - do - { - OUString sProperty = sExtendedAttrs.getToken( 0, ';', nIndex ); - - sal_Int32 nColonPos = 0; - OString sPropertyName = OUStringToOString( sProperty.getToken( 0, ':', nColonPos ), - RTL_TEXTENCODING_UTF8 ); - OString sPropertyValue = OUStringToOString( sProperty.getToken( 0, ':', nColonPos ), - RTL_TEXTENCODING_UTF8 ); - - pSet = attribute_set_prepend( pSet, - atk_text_attribute_register( sPropertyName.getStr() ), - g_strdup_printf( "%s", sPropertyValue.getStr() ) ); - } - while ( nIndex >= 0 && nIndex < sExtendedAttrs.getLength() ); - - return pSet; -} - -AtkAttributeSet* attribute_set_prepend_misspelled( AtkAttributeSet* attribute_set ) -{ - if( ATK_TEXT_ATTR_INVALID == atk_text_attribute_misspelled ) - atk_text_attribute_misspelled = atk_text_attribute_register( "text-spelling" ); - - attribute_set = attribute_set_prepend( attribute_set, atk_text_attribute_misspelled, - g_strdup_printf( "misspelled" ) ); - - return attribute_set; -} - -// #i92232# -AtkAttributeSet* attribute_set_prepend_tracked_change_insertion( AtkAttributeSet* attribute_set ) -{ - if ( ATK_TEXT_ATTR_INVALID == atk_text_attribute_tracked_change ) - { - atk_text_attribute_tracked_change = atk_text_attribute_register( "text-tracked-change" ); - } - - attribute_set = attribute_set_prepend( attribute_set, - atk_text_attribute_tracked_change, - g_strdup_printf( "insertion" ) ); - - return attribute_set; -} - -AtkAttributeSet* attribute_set_prepend_tracked_change_deletion( AtkAttributeSet* attribute_set ) -{ - if ( ATK_TEXT_ATTR_INVALID == atk_text_attribute_tracked_change ) - { - atk_text_attribute_tracked_change = atk_text_attribute_register( "text-tracked-change" ); - } - - attribute_set = attribute_set_prepend( attribute_set, - atk_text_attribute_tracked_change, - g_strdup_printf( "deletion" ) ); - - return attribute_set; -} - -AtkAttributeSet* attribute_set_prepend_tracked_change_formatchange( AtkAttributeSet* attribute_set ) -{ - if ( ATK_TEXT_ATTR_INVALID == atk_text_attribute_tracked_change ) - { - atk_text_attribute_tracked_change = atk_text_attribute_register( "text-tracked-change" ); - } - - attribute_set = attribute_set_prepend( attribute_set, - atk_text_attribute_tracked_change, - g_strdup_printf( "attribute-change" ) ); - - return attribute_set; -} - -/*****************************************************************************/ - -struct AtkTextAttrMapping -{ - const char * name; - TextPropertyValueFunc const toPropertyValue; -}; - -const AtkTextAttrMapping g_TextAttrMap[] = -{ - { "", InvalidValue }, // ATK_TEXT_ATTR_INVALID = 0 - { "ParaLeftMargin", UnitString2CMM }, // ATK_TEXT_ATTR_LEFT_MARGIN - { "ParaRightMargin", UnitString2CMM }, // ATK_TEXT_ATTR_RIGHT_MARGIN - { "ParaFirstLineIndent", UnitString2CMM }, // ATK_TEXT_ATTR_INDENT - { "CharHidden", String2Bool }, // ATK_TEXT_ATTR_INVISIBLE - { "", InvalidValue }, // ATK_TEXT_ATTR_EDITABLE - { "ParaTopMargin", UnitString2CMM }, // ATK_TEXT_ATTR_PIXELS_ABOVE_LINES - { "ParaBottomMargin", UnitString2CMM }, // ATK_TEXT_ATTR_PIXELS_BELOW_LINES - { "", InvalidValue }, // ATK_TEXT_ATTR_PIXELS_INSIDE_WRAP - { "", InvalidValue }, // ATK_TEXT_ATTR_BG_FULL_HEIGHT - { "", InvalidValue }, // ATK_TEXT_ATTR_RISE - { "CharUnderline", String2Underline }, // ATK_TEXT_ATTR_UNDERLINE - { "CharStrikeout", String2Strikeout }, // ATK_TEXT_ATTR_STRIKETHROUGH - { "CharHeight", String2Float }, // ATK_TEXT_ATTR_SIZE - { "CharScaleWidth", String2Scale }, // ATK_TEXT_ATTR_SCALE - { "CharWeight", String2Weight }, // ATK_TEXT_ATTR_WEIGHT - { "CharLocale", String2Locale }, // ATK_TEXT_ATTR_LANGUAGE - { "CharFontName", SetString }, // ATK_TEXT_ATTR_FAMILY_NAME - { "CharBackColor", String2Color }, // ATK_TEXT_ATTR_BG_COLOR - { "CharColor", String2Color }, // ATK_TEXT_ATTR_FG_COLOR - { "", InvalidValue }, // ATK_TEXT_ATTR_BG_STIPPLE - { "", InvalidValue }, // ATK_TEXT_ATTR_FG_STIPPLE - { "", InvalidValue }, // ATK_TEXT_ATTR_WRAP_MODE - { "", InvalidValue }, // ATK_TEXT_ATTR_DIRECTION - { "ParaAdjust", Justification2Adjust }, // ATK_TEXT_ATTR_JUSTIFICATION - { "", InvalidValue }, // ATK_TEXT_ATTR_STRETCH - { "CharCaseMap", String2CaseMap }, // ATK_TEXT_ATTR_VARIANT - { "CharPosture", Style2FontSlant } // ATK_TEXT_ATTR_STYLE -}; - -/*****************************************************************************/ - -bool -attribute_set_map_to_property_values( - AtkAttributeSet* attribute_set, - uno::Sequence< beans::PropertyValue >& rValueList ) -{ - // Ensure enough space .. - uno::Sequence< beans::PropertyValue > aAttributeList (SAL_N_ELEMENTS(g_TextAttrMap)); - - sal_Int32 nIndex = 0; - for( GSList * item = attribute_set; item != nullptr; item = g_slist_next( item ) ) - { - AtkAttribute* attribute = reinterpret_cast<AtkAttribute *>(item); - - AtkTextAttribute text_attr = atk_text_attribute_for_name( attribute->name ); - if( text_attr < SAL_N_ELEMENTS(g_TextAttrMap) ) - { - if( g_TextAttrMap[text_attr].name[0] != '\0' ) - { - if( ! g_TextAttrMap[text_attr].toPropertyValue( aAttributeList[nIndex].Value, attribute->value) ) - return false; - - aAttributeList[nIndex].Name = OUString::createFromAscii( g_TextAttrMap[text_attr].name ); - aAttributeList[nIndex].State = beans::PropertyState_DIRECT_VALUE; - ++nIndex; - } - } - else - { - // Unsupported text attribute - return false; - } - } - - aAttributeList.realloc( nIndex ); - rValueList = aAttributeList; - return true; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/a11y/atkutil.cxx b/vcl/unx/gtk/a11y/atkutil.cxx deleted file mode 100644 index 50ed2793bbf0..000000000000 --- a/vcl/unx/gtk/a11y/atkutil.cxx +++ /dev/null @@ -1,789 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifdef AIX -#define _LINUX_SOURCE_COMPAT -#include <sys/timer.h> -#undef _LINUX_SOURCE_COMPAT -#endif - -#include <com/sun/star/accessibility/XAccessibleContext.hpp> -#include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp> -#include <com/sun/star/accessibility/XAccessibleSelection.hpp> -#include <com/sun/star/accessibility/AccessibleEventId.hpp> -#include <com/sun/star/accessibility/AccessibleStateType.hpp> -#include <com/sun/star/accessibility/XAccessibleText.hpp> -#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> -#include <cppuhelper/implbase.hxx> -#include <cppuhelper/weakref.hxx> -#include <rtl/ref.hxx> -#include <sal/log.hxx> - -#include <vcl/svapp.hxx> -#include <vcl/window.hxx> -#include <vcl/menu.hxx> -#include <vcl/toolbox.hxx> - -#include <unx/gtk/gtkdata.hxx> -#include "atkwrapper.hxx" -#include "atkutil.hxx" - -#include <gtk/gtk.h> -#include <config_version.h> - -#include <cassert> -#include <set> - -using namespace ::com::sun::star; - -namespace -{ - struct theNextFocusObject : - public rtl::Static< uno::WeakReference< accessibility::XAccessible >, theNextFocusObject> - { - }; -} - -static guint focus_notify_handler = 0; - -/*****************************************************************************/ - -extern "C" { - -static gboolean -atk_wrapper_focus_idle_handler (gpointer data) -{ - SolarMutexGuard aGuard; - - focus_notify_handler = 0; - - uno::Reference< accessibility::XAccessible > xAccessible = theNextFocusObject::get(); - if( xAccessible.get() == static_cast < accessibility::XAccessible * > (data) ) - { - AtkObject *atk_obj = xAccessible.is() ? atk_object_wrapper_ref( xAccessible ) : nullptr; - // Gail does not notify focus changes to NULL, so do we .. - if( atk_obj ) - { - SAL_WNODEPRECATED_DECLARATIONS_PUSH - atk_focus_tracker_notify(atk_obj); - SAL_WNODEPRECATED_DECLARATIONS_POP - // #i93269# - // emit text_caret_moved event for <XAccessibleText> object, - // if cursor is inside the <XAccessibleText> object. - // also emit state-changed:focused event under the same condition. - { - AtkObjectWrapper* wrapper_obj = ATK_OBJECT_WRAPPER (atk_obj); - if( wrapper_obj && !wrapper_obj->mpText.is() ) - { - wrapper_obj->mpText.set(wrapper_obj->mpContext, css::uno::UNO_QUERY); - if ( wrapper_obj->mpText.is() ) - { - gint caretPos = -1; - - try { - caretPos = wrapper_obj->mpText->getCaretPosition(); - } - catch(const uno::Exception&) { - g_warning( "Exception in getCaretPosition()" ); - } - - if ( caretPos != -1 ) - { - atk_object_notify_state_change( atk_obj, ATK_STATE_FOCUSED, TRUE ); - g_signal_emit_by_name( atk_obj, "text_caret_moved", caretPos ); - } - } - } - } - g_object_unref(atk_obj); - } - } - - return false; -} - -} // extern "C" - -/*****************************************************************************/ - -static void -atk_wrapper_focus_tracker_notify_when_idle( const uno::Reference< accessibility::XAccessible > &xAccessible ) -{ - if( focus_notify_handler ) - g_source_remove(focus_notify_handler); - - theNextFocusObject::get() = xAccessible; - - focus_notify_handler = g_idle_add (atk_wrapper_focus_idle_handler, xAccessible.get()); -} - -/*****************************************************************************/ - -class DocumentFocusListener : - public ::cppu::WeakImplHelper< accessibility::XAccessibleEventListener > -{ - - std::set< uno::Reference< uno::XInterface > > m_aRefList; - -public: - /// @throws lang::IndexOutOfBoundsException - /// @throws uno::RuntimeException - void attachRecursive( - const uno::Reference< accessibility::XAccessible >& xAccessible - ); - - /// @throws lang::IndexOutOfBoundsException - /// @throws uno::RuntimeException - void attachRecursive( - const uno::Reference< accessibility::XAccessible >& xAccessible, - const uno::Reference< accessibility::XAccessibleContext >& xContext - ); - - /// @throws lang::IndexOutOfBoundsException - /// @throws uno::RuntimeException - void attachRecursive( - const uno::Reference< accessibility::XAccessible >& xAccessible, - const uno::Reference< accessibility::XAccessibleContext >& xContext, - const uno::Reference< accessibility::XAccessibleStateSet >& xStateSet - ); - - /// @throws lang::IndexOutOfBoundsException - /// @throws uno::RuntimeException - void detachRecursive( - const uno::Reference< accessibility::XAccessible >& xAccessible - ); - - /// @throws lang::IndexOutOfBoundsException - /// @throws uno::RuntimeException - void detachRecursive( - const uno::Reference< accessibility::XAccessibleContext >& xContext - ); - - /// @throws lang::IndexOutOfBoundsException - /// @throws uno::RuntimeException - void detachRecursive( - const uno::Reference< accessibility::XAccessibleContext >& xContext, - const uno::Reference< accessibility::XAccessibleStateSet >& xStateSet - ); - - /// @throws lang::IndexOutOfBoundsException - /// @throws uno::RuntimeException - static uno::Reference< accessibility::XAccessible > getAccessible(const lang::EventObject& aEvent ); - - // XEventListener - virtual void SAL_CALL disposing( const lang::EventObject& Source ) override; - - // XAccessibleEventListener - virtual void SAL_CALL notifyEvent( const accessibility::AccessibleEventObject& aEvent ) override; -}; - -/*****************************************************************************/ - -void DocumentFocusListener::disposing( const lang::EventObject& aEvent ) -{ - - // Unref the object here, but do not remove as listener since the object - // might no longer be in a state that safely allows this. - if( aEvent.Source.is() ) - m_aRefList.erase(aEvent.Source); - -} - -/*****************************************************************************/ - -void DocumentFocusListener::notifyEvent( const accessibility::AccessibleEventObject& aEvent ) -{ - try { - switch( aEvent.EventId ) - { - case accessibility::AccessibleEventId::STATE_CHANGED: - { - sal_Int16 nState = accessibility::AccessibleStateType::INVALID; - aEvent.NewValue >>= nState; - - if( accessibility::AccessibleStateType::FOCUSED == nState ) - atk_wrapper_focus_tracker_notify_when_idle( getAccessible(aEvent) ); - - break; - } - - case accessibility::AccessibleEventId::CHILD: - { - uno::Reference< accessibility::XAccessible > xChild; - if( (aEvent.OldValue >>= xChild) && xChild.is() ) - detachRecursive(xChild); - - if( (aEvent.NewValue >>= xChild) && xChild.is() ) - attachRecursive(xChild); - - break; - } - - case accessibility::AccessibleEventId::INVALIDATE_ALL_CHILDREN: - SAL_INFO("vcl.a11y", "Invalidate all children called"); - break; - - default: - break; - } - } - catch( const lang::IndexOutOfBoundsException& e ) - { - g_warning("Focused object has invalid index in parent"); - } -} - -/*****************************************************************************/ - -uno::Reference< accessibility::XAccessible > DocumentFocusListener::getAccessible(const lang::EventObject& aEvent ) -{ - uno::Reference< accessibility::XAccessible > xAccessible(aEvent.Source, uno::UNO_QUERY); - - if( xAccessible.is() ) - return xAccessible; - - uno::Reference< accessibility::XAccessibleContext > xContext(aEvent.Source, uno::UNO_QUERY); - - if( xContext.is() ) - { - uno::Reference< accessibility::XAccessible > xParent( xContext->getAccessibleParent() ); - if( xParent.is() ) - { - uno::Reference< accessibility::XAccessibleContext > xParentContext( xParent->getAccessibleContext() ); - if( xParentContext.is() ) - { - return xParentContext->getAccessibleChild( xContext->getAccessibleIndexInParent() ); - } - } - } - - return uno::Reference< accessibility::XAccessible >(); -} - -/*****************************************************************************/ - -void DocumentFocusListener::attachRecursive( - const uno::Reference< accessibility::XAccessible >& xAccessible -) -{ - uno::Reference< accessibility::XAccessibleContext > xContext = - xAccessible->getAccessibleContext(); - - if( xContext.is() ) - attachRecursive(xAccessible, xContext); -} - -/*****************************************************************************/ - -void DocumentFocusListener::attachRecursive( - const uno::Reference< accessibility::XAccessible >& xAccessible, - const uno::Reference< accessibility::XAccessibleContext >& xContext -) -{ - uno::Reference< accessibility::XAccessibleStateSet > xStateSet = - xContext->getAccessibleStateSet(); - - if( xStateSet.is() ) - attachRecursive(xAccessible, xContext, xStateSet); -} - -/*****************************************************************************/ - -void DocumentFocusListener::attachRecursive( - const uno::Reference< accessibility::XAccessible >& xAccessible, - const uno::Reference< accessibility::XAccessibleContext >& xContext, - const uno::Reference< accessibility::XAccessibleStateSet >& xStateSet -) -{ - if( xStateSet->contains(accessibility::AccessibleStateType::FOCUSED ) ) - atk_wrapper_focus_tracker_notify_when_idle( xAccessible ); - - uno::Reference< accessibility::XAccessibleEventBroadcaster > xBroadcaster(xContext, uno::UNO_QUERY); - - if (!xBroadcaster.is()) - return; - - // If not already done, add the broadcaster to the list and attach as listener. - const uno::Reference< uno::XInterface >& xInterface = xBroadcaster; - if( m_aRefList.insert(xInterface).second ) - { - xBroadcaster->addAccessibleEventListener(static_cast< accessibility::XAccessibleEventListener *>(this)); - - if( ! xStateSet->contains(accessibility::AccessibleStateType::MANAGES_DESCENDANTS ) ) - { - sal_Int32 n, nmax = xContext->getAccessibleChildCount(); - for( n = 0; n < nmax; n++ ) - { - uno::Reference< accessibility::XAccessible > xChild( xContext->getAccessibleChild( n ) ); - - if( xChild.is() ) - attachRecursive(xChild); - } - } - } -} - -/*****************************************************************************/ - -void DocumentFocusListener::detachRecursive( - const uno::Reference< accessibility::XAccessible >& xAccessible -) -{ - uno::Reference< accessibility::XAccessibleContext > xContext = - xAccessible->getAccessibleContext(); - - if( xContext.is() ) - detachRecursive(xContext); -} - -/*****************************************************************************/ - -void DocumentFocusListener::detachRecursive( - const uno::Reference< accessibility::XAccessibleContext >& xContext -) -{ - uno::Reference< accessibility::XAccessibleStateSet > xStateSet = - xContext->getAccessibleStateSet(); - - if( xStateSet.is() ) - detachRecursive(xContext, xStateSet); -} - -/*****************************************************************************/ - -void DocumentFocusListener::detachRecursive( - const uno::Reference< accessibility::XAccessibleContext >& xContext, - const uno::Reference< accessibility::XAccessibleStateSet >& xStateSet -) -{ - uno::Reference< accessibility::XAccessibleEventBroadcaster > xBroadcaster(xContext, uno::UNO_QUERY); - - if( xBroadcaster.is() && 0 < m_aRefList.erase(xBroadcaster) ) - { - xBroadcaster->removeAccessibleEventListener(static_cast< accessibility::XAccessibleEventListener *>(this)); - - if( ! xStateSet->contains(accessibility::AccessibleStateType::MANAGES_DESCENDANTS ) ) - { - sal_Int32 n, nmax = xContext->getAccessibleChildCount(); - for( n = 0; n < nmax; n++ ) - { - uno::Reference< accessibility::XAccessible > xChild( xContext->getAccessibleChild( n ) ); - - if( xChild.is() ) - detachRecursive(xChild); - } - } - } -} - -/*****************************************************************************/ - -/* - * page tabs in gtk are widgets, so we need to simulate focus events for those - */ - -static void handle_tabpage_activated(vcl::Window *pWindow) -{ - uno::Reference< accessibility::XAccessible > xAccessible = - pWindow->GetAccessible(); - - if( ! xAccessible.is() ) - return; - - uno::Reference< accessibility::XAccessibleSelection > xSelection( - xAccessible->getAccessibleContext(), uno::UNO_QUERY); - - if( xSelection.is() ) - atk_wrapper_focus_tracker_notify_when_idle( xSelection->getSelectedAccessibleChild(0) ); -} - -/*****************************************************************************/ - -/* - * toolbar items in gtk are widgets, so we need to simulate focus events for those - */ - -static void notify_toolbox_item_focus(ToolBox *pToolBox) -{ - uno::Reference< accessibility::XAccessible > xAccessible = - pToolBox->GetAccessible(); - - if( ! xAccessible.is() ) - return; - - uno::Reference< accessibility::XAccessibleContext > xContext = - xAccessible->getAccessibleContext(); - - if( ! xContext.is() ) - return; - - ToolBox::ImplToolItems::size_type nPos = pToolBox->GetItemPos( pToolBox->GetHighlightItemId() ); - if( nPos != ToolBox::ITEM_NOTFOUND ) - atk_wrapper_focus_tracker_notify_when_idle( xContext->getAccessibleChild( nPos ) ); - //TODO: ToolBox::ImplToolItems::size_type -> sal_Int32 -} - -static void handle_toolbox_highlight(vcl::Window *pWindow) -{ - ToolBox *pToolBox = static_cast <ToolBox *> (pWindow); - - // Make sure either the toolbox or its parent toolbox has the focus - if ( ! pToolBox->HasFocus() ) - { - ToolBox* pToolBoxParent = dynamic_cast< ToolBox* >( pToolBox->GetParent() ); - if ( ! pToolBoxParent || ! pToolBoxParent->HasFocus() ) - return; - } - - notify_toolbox_item_focus(pToolBox); -} - -static void handle_toolbox_highlightoff(vcl::Window const *pWindow) -{ - ToolBox* pToolBoxParent = dynamic_cast< ToolBox* >( pWindow->GetParent() ); - - // Notify when leaving sub toolboxes - if( pToolBoxParent && pToolBoxParent->HasFocus() ) - notify_toolbox_item_focus( pToolBoxParent ); -} - -/*****************************************************************************/ - -static void create_wrapper_for_child( - const uno::Reference< accessibility::XAccessibleContext >& xContext, - sal_Int32 index) -{ - if( xContext.is() ) - { - uno::Reference< accessibility::XAccessible > xChild(xContext->getAccessibleChild(index)); - if( xChild.is() ) - { - // create the wrapper object - it will survive the unref unless it is a transient object - g_object_unref( atk_object_wrapper_ref( xChild ) ); - } - } -} - -/*****************************************************************************/ - -static void handle_toolbox_buttonchange(VclWindowEvent const *pEvent) -{ - vcl::Window* pWindow = pEvent->GetWindow(); - sal_Int32 index = static_cast<sal_Int32>(reinterpret_cast<sal_IntPtr>(pEvent->GetData())); - - if( pWindow && pWindow->IsReallyVisible() ) - { - uno::Reference< accessibility::XAccessible > xAccessible(pWindow->GetAccessible()); - if( xAccessible.is() ) - { - create_wrapper_for_child(xAccessible->getAccessibleContext(), index); - } - } -} - -/*****************************************************************************/ - -namespace { - -struct WindowList { - ~WindowList() { assert(list.empty()); }; - // needs to be empty already on DeInitVCL, but at least check it's empty - // on exit - - std::set< VclPtr<vcl::Window> > list; -}; - -WindowList g_aWindowList; - -} - -DocumentFocusListener & GtkSalData::GetDocumentFocusListener() -{ - if (!m_pDocumentFocusListener) - { - m_pDocumentFocusListener = new DocumentFocusListener; - m_xDocumentFocusListener.set(m_pDocumentFocusListener); - } - return *m_pDocumentFocusListener; -} - -static void handle_get_focus(::VclWindowEvent const * pEvent) -{ - GtkSalData *const pSalData(GetGtkSalData()); - assert(pSalData); - - DocumentFocusListener & rDocumentFocusListener(pSalData->GetDocumentFocusListener()); - - vcl::Window *pWindow = pEvent->GetWindow(); - - // The menu bar is handled through VclEventId::MenuHighlightED - if( ! pWindow || !pWindow->IsReallyVisible() || pWindow->GetType() == WindowType::MENUBARWINDOW ) - return; - - // ToolBoxes are handled through VclEventId::ToolboxHighlight - if( pWindow->GetType() == WindowType::TOOLBOX ) - return; - - if( pWindow->GetType() == WindowType::TABCONTROL ) - { - handle_tabpage_activated( pWindow ); - return; - } - - uno::Reference< accessibility::XAccessible > xAccessible = - pWindow->GetAccessible(); - - if( ! xAccessible.is() ) - return; - - uno::Reference< accessibility::XAccessibleContext > xContext = - xAccessible->getAccessibleContext(); - - if( ! xContext.is() ) - return; - - uno::Reference< accessibility::XAccessibleStateSet > xStateSet = - xContext->getAccessibleStateSet(); - - if( ! xStateSet.is() ) - return; - -/* the UNO ToolBox wrapper does not (yet?) support XAccessibleSelection, so we - * need to add listeners to the children instead of re-using the tabpage stuff - */ - if( xStateSet->contains(accessibility::AccessibleStateType::FOCUSED) && - ( pWindow->GetType() != WindowType::TREELISTBOX ) ) - { - atk_wrapper_focus_tracker_notify_when_idle( xAccessible ); - } - else - { - if( g_aWindowList.list.insert(pWindow).second ) - { - try - { - rDocumentFocusListener.attachRecursive(xAccessible, xContext, xStateSet); - } - catch (const uno::Exception&) - { - g_warning( "Exception caught processing focus events" ); - } - } - } -} - -/*****************************************************************************/ - -static void handle_menu_highlighted(::VclMenuEvent const * pEvent) -{ - try - { - Menu* pMenu = pEvent->GetMenu(); - sal_uInt16 nPos = pEvent->GetItemPos(); - - if( pMenu && nPos != 0xFFFF) - { - uno::Reference< accessibility::XAccessible > xAccessible ( pMenu->GetAccessible() ); - - if( xAccessible.is() ) - { - uno::Reference< accessibility::XAccessibleContext > xContext ( xAccessible->getAccessibleContext() ); - - if( xContext.is() ) - atk_wrapper_focus_tracker_notify_when_idle( xContext->getAccessibleChild( nPos ) ); - } - } - } - catch (const uno::Exception&) - { - g_warning( "Exception caught processing menu highlight events" ); - } -} - -/*****************************************************************************/ - -static void WindowEventHandler(void *, VclSimpleEvent& rEvent) -{ - try - { - switch (rEvent.GetId()) - { - case VclEventId::WindowShow: - break; - case VclEventId::WindowHide: - break; - case VclEventId::WindowClose: - break; - case VclEventId::WindowGetFocus: - handle_get_focus(static_cast< ::VclWindowEvent const * >(&rEvent)); - break; - case VclEventId::WindowLoseFocus: - break; - case VclEventId::WindowMinimize: - break; - case VclEventId::WindowNormalize: - break; - case VclEventId::WindowKeyInput: - case VclEventId::WindowKeyUp: - case VclEventId::WindowCommand: - case VclEventId::WindowMouseMove: - break; - - case VclEventId::MenuHighlight: - if (const VclMenuEvent* pMenuEvent = dynamic_cast<const VclMenuEvent*>(&rEvent)) - { - handle_menu_highlighted(pMenuEvent); - } - else if (const VclAccessibleEvent* pAccEvent = dynamic_cast<const VclAccessibleEvent*>(&rEvent)) - { - const uno::Reference< accessibility::XAccessible >& xAccessible = pAccEvent->GetAccessible(); - if (xAccessible.is()) - atk_wrapper_focus_tracker_notify_when_idle(xAccessible); - } - break; - - case VclEventId::ToolboxHighlight: - handle_toolbox_highlight(static_cast< ::VclWindowEvent const * >(&rEvent)->GetWindow()); - break; - - case VclEventId::ToolboxButtonStateChanged: - handle_toolbox_buttonchange(static_cast< ::VclWindowEvent const * >(&rEvent)); - break; - - case VclEventId::ObjectDying: - g_aWindowList.list.erase( static_cast< ::VclWindowEvent const * >(&rEvent)->GetWindow() ); - [[fallthrough]]; - case VclEventId::ToolboxHighlightOff: - handle_toolbox_highlightoff(static_cast< ::VclWindowEvent const * >(&rEvent)->GetWindow()); - break; - - case VclEventId::TabpageActivate: - handle_tabpage_activated(static_cast< ::VclWindowEvent const * >(&rEvent)->GetWindow()); - break; - - case VclEventId::ComboboxSetText: - // This looks quite strange to me. Stumbled over this when fixing #i104290#. - // This kicked in when leaving the combobox in the toolbar, after that the events worked. - // I guess this was a try to work around missing combobox events, which didn't do the full job, and shouldn't be necessary anymore. - // Fix for #i104290# was done in toolkit/source/awt/vclxaccessiblecomponent, FOCUSED state for compound controls in general. - // create_wrapper_for_children(static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow()); - break; - - default: - break; - } - } - catch (const lang::IndexOutOfBoundsException&) - { - g_warning("Focused object has invalid index in parent"); - } -} - -static Link<VclSimpleEvent&,void> g_aEventListenerLink( nullptr, WindowEventHandler ); - -/*****************************************************************************/ - -extern "C" { - -static const gchar * -ooo_atk_util_get_toolkit_name() -{ - return "VCL"; -} - -/*****************************************************************************/ - -static const gchar * -ooo_atk_util_get_toolkit_version() -{ - return LIBO_VERSION_DOTTED; -} - -/*****************************************************************************/ - -/* - * GObject inheritance - */ - -static void -ooo_atk_util_class_init (AtkUtilClass *) -{ - AtkUtilClass *atk_class; - gpointer data; - - data = g_type_class_peek (ATK_TYPE_UTIL); - atk_class = ATK_UTIL_CLASS (data); - - atk_class->get_toolkit_name = ooo_atk_util_get_toolkit_name; - atk_class->get_toolkit_version = ooo_atk_util_get_toolkit_version; - - ooo_atk_util_ensure_event_listener(); -} - -} // extern "C" - -void ooo_atk_util_ensure_event_listener() -{ - static bool bInited; - if (!bInited) - { - Application::AddEventListener( g_aEventListenerLink ); - bInited = true; - } -} - -GType -ooo_atk_util_get_type() -{ - static GType type = 0; - - if (!type) - { - GType parent_type = g_type_from_name( "GailUtil" ); - - if( ! parent_type ) - { - g_warning( "Unknown type: GailUtil" ); - parent_type = ATK_TYPE_UTIL; - } - - GTypeQuery type_query; - g_type_query( parent_type, &type_query ); - - static const GTypeInfo typeInfo = - { - static_cast<guint16>(type_query.class_size), - nullptr, - nullptr, - reinterpret_cast<GClassInitFunc>(ooo_atk_util_class_init), - nullptr, - nullptr, - static_cast<guint16>(type_query.instance_size), - 0, - nullptr, - nullptr - } ; - - type = g_type_register_static (parent_type, "OOoUtil", &typeInfo, GTypeFlags(0)) ; - } - - return type; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/a11y/atkvalue.cxx b/vcl/unx/gtk/a11y/atkvalue.cxx deleted file mode 100644 index f5e45d3b2556..000000000000 --- a/vcl/unx/gtk/a11y/atkvalue.cxx +++ /dev/null @@ -1,138 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "atkwrapper.hxx" - -#include <com/sun/star/accessibility/XAccessibleValue.hpp> - -#include <string.h> - -using namespace ::com::sun::star; - -/// @throws uno::RuntimeException -static css::uno::Reference<css::accessibility::XAccessibleValue> - getValue( AtkValue *pValue ) -{ - AtkObjectWrapper *pWrap = ATK_OBJECT_WRAPPER( pValue ); - if( pWrap ) - { - if( !pWrap->mpValue.is() ) - { - pWrap->mpValue.set(pWrap->mpContext, css::uno::UNO_QUERY); - } - - return pWrap->mpValue; - } - - return css::uno::Reference<css::accessibility::XAccessibleValue>(); -} - -static void anyToGValue( const uno::Any& aAny, GValue *pValue ) -{ - // FIXME: expand to lots of types etc. - double aDouble=0; - aAny >>= aDouble; - - memset( pValue, 0, sizeof( GValue ) ); - g_value_init( pValue, G_TYPE_DOUBLE ); - g_value_set_double( pValue, aDouble ); -} - -extern "C" { - -static void -value_wrapper_get_current_value( AtkValue *value, - GValue *gval ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleValue> pValue - = getValue( value ); - if( pValue.is() ) - anyToGValue( pValue->getCurrentValue(), gval ); - } - catch(const uno::Exception&) { - g_warning( "Exception in getCurrentValue()" ); - } -} - -static void -value_wrapper_get_maximum_value( AtkValue *value, - GValue *gval ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleValue> pValue - = getValue( value ); - if( pValue.is() ) - anyToGValue( pValue->getMaximumValue(), gval ); - } - catch(const uno::Exception&) { - g_warning( "Exception in getCurrentValue()" ); - } -} - -static void -value_wrapper_get_minimum_value( AtkValue *value, - GValue *gval ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleValue> pValue - = getValue( value ); - if( pValue.is() ) - anyToGValue( pValue->getMinimumValue(), gval ); - } - catch(const uno::Exception&) { - g_warning( "Exception in getCurrentValue()" ); - } -} - -static gboolean -value_wrapper_set_current_value( AtkValue *value, - const GValue *gval ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleValue> pValue - = getValue( value ); - if( pValue.is() ) - { - // FIXME - this needs expanding - double aDouble = g_value_get_double( gval ); - return pValue->setCurrentValue( uno::Any(aDouble) ); - } - } - catch(const uno::Exception&) { - g_warning( "Exception in getCurrentValue()" ); - } - - return FALSE; -} - -} // extern "C" - -void -valueIfaceInit (AtkValueIface *iface) -{ - g_return_if_fail (iface != nullptr); - - iface->get_current_value = value_wrapper_get_current_value; - iface->get_maximum_value = value_wrapper_get_maximum_value; - iface->get_minimum_value = value_wrapper_get_minimum_value; - iface->set_current_value = value_wrapper_set_current_value; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/a11y/atkwindow.cxx b/vcl/unx/gtk/a11y/atkwindow.cxx deleted file mode 100644 index eb72edf4908c..000000000000 --- a/vcl/unx/gtk/a11y/atkwindow.cxx +++ /dev/null @@ -1,330 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include <unx/gtk/gtkframe.hxx> -#include <vcl/svapp.hxx> -#include <vcl/window.hxx> -#include <vcl/popupmenuwindow.hxx> -#include <sal/log.hxx> - -#include "atkwindow.hxx" -#include "atkwrapper.hxx" -#include "atkregistry.hxx" - -#include <com/sun/star/accessibility/AccessibleRole.hpp> - -using namespace ::com::sun::star::accessibility; -using namespace ::com::sun::star::uno; - -extern "C" { - -static void (* window_real_initialize) (AtkObject *obj, gpointer data) = nullptr; -static void (* window_real_finalize) (GObject *obj) = nullptr; - -static void -init_from_window( AtkObject *accessible, vcl::Window const *pWindow ) -{ - static AtkRole aDefaultRole = ATK_ROLE_INVALID; - - // Special role for sub-menu and combo-box popups that are exposed directly - // by their parents already. - if( aDefaultRole == ATK_ROLE_INVALID ) - { - SAL_WNODEPRECATED_DECLARATIONS_PUSH - aDefaultRole = atk_role_register( "redundant object" ); - SAL_WNODEPRECATED_DECLARATIONS_POP - } - - AtkRole role = aDefaultRole; - - // Determine the appropriate role for the GtkWindow - switch( pWindow->GetAccessibleRole() ) - { - case AccessibleRole::ALERT: - role = ATK_ROLE_ALERT; - break; - - case AccessibleRole::DIALOG: - role = ATK_ROLE_DIALOG; - break; - - case AccessibleRole::FRAME: - role = ATK_ROLE_FRAME; - break; - - /* Ignore window objects for sub-menus, combo- and list boxes, - * which are exposed as children of their parents. - */ - case AccessibleRole::WINDOW: - { - WindowType type = WindowType::WINDOW; - bool parentIsMenuFloatingWindow = false; - - vcl::Window *pParent = pWindow->GetParent(); - if( pParent ) { - type = pParent->GetType(); - parentIsMenuFloatingWindow = pParent->IsMenuFloatingWindow(); - } - - if( (WindowType::LISTBOX != type) && (WindowType::COMBOBOX != type) && - (WindowType::MENUBARWINDOW != type) && ! parentIsMenuFloatingWindow ) - { - role = ATK_ROLE_WINDOW; - } - } - break; - - default: - { - vcl::Window *pChild = pWindow->GetWindow(GetWindowType::FirstChild); - if( pChild ) - { - if( WindowType::HELPTEXTWINDOW == pChild->GetType() ) - { - role = ATK_ROLE_TOOL_TIP; - pChild->SetAccessibleRole( AccessibleRole::LABEL ); - accessible->name = g_strdup( OUStringToOString( pChild->GetText(), RTL_TEXTENCODING_UTF8 ).getStr() ); - } - else if ( pWindow->GetType() == WindowType::BORDERWINDOW && pChild->GetType() == WindowType::FLOATINGWINDOW ) - { - PopupMenuFloatingWindow* p = dynamic_cast<PopupMenuFloatingWindow*>(pChild); - if (p && p->IsPopupMenu() && p->GetMenuStackLevel() == 0) - { - // This is a top-level menu popup. Register it. - role = ATK_ROLE_POPUP_MENU; - pChild->SetAccessibleRole( AccessibleRole::POPUP_MENU ); - accessible->name = g_strdup( OUStringToOString( pChild->GetText(), RTL_TEXTENCODING_UTF8 ).getStr() ); - } - } - } - break; - } - } - - accessible->role = role; -} - -/*****************************************************************************/ - -static gboolean -ooo_window_wrapper_clear_focus(gpointer) -{ - SolarMutexGuard aGuard; - SAL_WNODEPRECATED_DECLARATIONS_PUSH - atk_focus_tracker_notify( nullptr ); - SAL_WNODEPRECATED_DECLARATIONS_POP - return false; -} - -/*****************************************************************************/ - -static gboolean -ooo_window_wrapper_real_focus_gtk (GtkWidget *, GdkEventFocus *) -{ - g_idle_add( ooo_window_wrapper_clear_focus, nullptr ); - return false; -} - -static gboolean ooo_tooltip_map( GtkWidget* pToolTip, gpointer ) -{ - AtkObject* pAccessible = gtk_widget_get_accessible( pToolTip ); - if( pAccessible ) - atk_object_notify_state_change( pAccessible, ATK_STATE_SHOWING, TRUE ); - return FALSE; -} - -static gboolean ooo_tooltip_unmap( GtkWidget* pToolTip, gpointer ) -{ - AtkObject* pAccessible = gtk_widget_get_accessible( pToolTip ); - if( pAccessible ) - atk_object_notify_state_change( pAccessible, ATK_STATE_SHOWING, FALSE ); - return FALSE; -} - -/*****************************************************************************/ - -static bool -isChildPopupMenu(vcl::Window* pWindow) -{ - vcl::Window* pChild = pWindow->GetAccessibleChildWindow(0); - if (!pChild) - return false; - - if (WindowType::FLOATINGWINDOW != pChild->GetType()) - return false; - - PopupMenuFloatingWindow* p = dynamic_cast<PopupMenuFloatingWindow*>(pChild); - if (!p) - return false; - - return p->IsPopupMenu(); -} - -static void -ooo_window_wrapper_real_initialize(AtkObject *obj, gpointer data) -{ - window_real_initialize(obj, data); - - GtkSalFrame *pFrame = GtkSalFrame::getFromWindow( GTK_WINDOW( data ) ); - if( pFrame ) - { - vcl::Window *pWindow = pFrame->GetWindow(); - if( pWindow ) - { - init_from_window( obj, pWindow ); - - Reference< XAccessible > xAccessible( pWindow->GetAccessible() ); - - /* We need the wrapper object for the top-level XAccessible to be - * in the wrapper registry when atk traverses the hierarchy up on - * focus events - */ - if( WindowType::BORDERWINDOW == pWindow->GetType() ) - { - if ( isChildPopupMenu(pWindow) ) - { - AtkObject *child = atk_object_wrapper_new( xAccessible, obj ); - ooo_wrapper_registry_add( xAccessible, child ); - } - else - { - ooo_wrapper_registry_add( xAccessible, obj ); - g_object_set_data( G_OBJECT(obj), "ooo:atk-wrapper-key", xAccessible.get() ); - } - } - else - { - AtkObject *child = atk_object_wrapper_new( xAccessible, obj ); - child->role = ATK_ROLE_FILLER; - if( (ATK_ROLE_DIALOG == obj->role) || (ATK_ROLE_ALERT == obj->role) ) - child->role = ATK_ROLE_OPTION_PANE; - ooo_wrapper_registry_add( xAccessible, child ); - } - } - } - - g_signal_connect_after( GTK_WIDGET( data ), "focus-out-event", - G_CALLBACK (ooo_window_wrapper_real_focus_gtk), - nullptr); - - if( obj->role == ATK_ROLE_TOOL_TIP ) - { - g_signal_connect_after( GTK_WIDGET( data ), "map-event", - G_CALLBACK (ooo_tooltip_map), - nullptr); - g_signal_connect_after( GTK_WIDGET( data ), "unmap-event", - G_CALLBACK (ooo_tooltip_unmap), - nullptr); - } -} - -/*****************************************************************************/ - -static void -ooo_window_wrapper_real_finalize (GObject *obj) -{ - ooo_wrapper_registry_remove( static_cast<XAccessible *>(g_object_get_data( obj, "ooo:atk-wrapper-key" ))); - window_real_finalize( obj ); -} - -/*****************************************************************************/ - -static void -ooo_window_wrapper_class_init (AtkObjectClass *klass, gpointer) -{ - AtkObjectClass *atk_class; - GObjectClass *gobject_class; - gpointer data; - - /* - * Patch the gobject vtable of GailWindow to refer to our instance of - * "initialize". - */ - - data = g_type_class_peek_parent( klass ); - atk_class = ATK_OBJECT_CLASS (data); - - window_real_initialize = atk_class->initialize; - atk_class->initialize = ooo_window_wrapper_real_initialize; - - gobject_class = G_OBJECT_CLASS (data); - - window_real_finalize = gobject_class->finalize; - gobject_class->finalize = ooo_window_wrapper_real_finalize; -} - -} // extern "C" - -/*****************************************************************************/ - -GType -ooo_window_wrapper_get_type() -{ - static GType type = 0; - - if (!type) - { - GType parent_type = g_type_from_name( "GailWindow" ); - - if( ! parent_type ) - { - SAL_INFO("vcl.a11y", "Unknown type: GailWindow"); - parent_type = ATK_TYPE_OBJECT; - } - - GTypeQuery type_query; - g_type_query( parent_type, &type_query ); - - static const GTypeInfo typeInfo = - { - static_cast<guint16>(type_query.class_size), - nullptr, - nullptr, - reinterpret_cast<GClassInitFunc>(ooo_window_wrapper_class_init), - nullptr, - nullptr, - static_cast<guint16>(type_query.instance_size), - 0, - nullptr, - nullptr - } ; - - type = g_type_register_static (parent_type, "OOoWindowAtkObject", &typeInfo, GTypeFlags(0)) ; - } - - return type; -} - -void restore_gail_window_vtable() -{ - AtkObjectClass *atk_class; - gpointer data; - - GType type = g_type_from_name( "GailWindow" ); - - if( type == G_TYPE_INVALID ) - return; - - data = g_type_class_peek( type ); - atk_class = ATK_OBJECT_CLASS (data); - - atk_class->initialize = window_real_initialize; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/a11y/atkwrapper.cxx b/vcl/unx/gtk/a11y/atkwrapper.cxx deleted file mode 100644 index cd439022cf2a..000000000000 --- a/vcl/unx/gtk/a11y/atkwrapper.cxx +++ /dev/null @@ -1,959 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include <com/sun/star/uno/Any.hxx> -#include <com/sun/star/uno/Type.hxx> -#include <com/sun/star/uno/Sequence.hxx> -#include <com/sun/star/accessibility/AccessibleRole.hpp> -#include <com/sun/star/accessibility/AccessibleRelation.hpp> -#include <com/sun/star/accessibility/AccessibleRelationType.hpp> -#include <com/sun/star/accessibility/AccessibleStateType.hpp> -#include <com/sun/star/accessibility/XAccessible.hpp> -#include <com/sun/star/accessibility/XAccessibleText.hpp> -#include <com/sun/star/accessibility/XAccessibleTextMarkup.hpp> -#include <com/sun/star/accessibility/XAccessibleTextAttributes.hpp> -#include <com/sun/star/accessibility/XAccessibleValue.hpp> -#include <com/sun/star/accessibility/XAccessibleAction.hpp> -#include <com/sun/star/accessibility/XAccessibleContext.hpp> -#include <com/sun/star/accessibility/XAccessibleContext2.hpp> -#include <com/sun/star/accessibility/XAccessibleComponent.hpp> -#include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp> -#include <com/sun/star/accessibility/XAccessibleMultiLineText.hpp> -#include <com/sun/star/accessibility/XAccessibleStateSet.hpp> -#include <com/sun/star/accessibility/XAccessibleRelationSet.hpp> -#include <com/sun/star/accessibility/XAccessibleTable.hpp> -#include <com/sun/star/accessibility/XAccessibleEditableText.hpp> -#include <com/sun/star/accessibility/XAccessibleExtendedAttributes.hpp> -#include <com/sun/star/accessibility/XAccessibleImage.hpp> -#include <com/sun/star/accessibility/XAccessibleHyperlink.hpp> -#include <com/sun/star/accessibility/XAccessibleHypertext.hpp> -#include <com/sun/star/accessibility/XAccessibleSelection.hpp> -#include <com/sun/star/awt/XExtendedToolkit.hpp> -#include <com/sun/star/awt/XTopWindow.hpp> -#include <com/sun/star/awt/XTopWindowListener.hpp> -#include <com/sun/star/awt/XWindow.hpp> -#include <com/sun/star/lang/XComponent.hpp> -#include <com/sun/star/lang/XServiceInfo.hpp> -#include <com/sun/star/lang/XInitialization.hpp> -#include <com/sun/star/lang/XMultiServiceFactory.hpp> -#include <com/sun/star/lang/XSingleServiceFactory.hpp> -#include <com/sun/star/beans/Property.hpp> - -#include <rtl/ref.hxx> -#include <rtl/strbuf.hxx> -#include <osl/diagnose.h> -#include <cppuhelper/factory.hxx> -#include <cppuhelper/queryinterface.hxx> - -#include "atkwrapper.hxx" -#include "atkregistry.hxx" -#include "atklistener.hxx" -#include "atktextattributes.hxx" - -#include <string.h> -#include <vector> - -using namespace ::com::sun::star; - -static GObjectClass *parent_class = nullptr; - -static AtkRelationType mapRelationType( sal_Int16 nRelation ) -{ - AtkRelationType type = ATK_RELATION_NULL; - - switch( nRelation ) - { - case accessibility::AccessibleRelationType::CONTENT_FLOWS_FROM: - type = ATK_RELATION_FLOWS_FROM; - break; - - case accessibility::AccessibleRelationType::CONTENT_FLOWS_TO: - type = ATK_RELATION_FLOWS_TO; - break; - - case accessibility::AccessibleRelationType::CONTROLLED_BY: - type = ATK_RELATION_CONTROLLED_BY; - break; - - case accessibility::AccessibleRelationType::CONTROLLER_FOR: - type = ATK_RELATION_CONTROLLER_FOR; - break; - - case accessibility::AccessibleRelationType::LABEL_FOR: - type = ATK_RELATION_LABEL_FOR; - break; - - case accessibility::AccessibleRelationType::LABELED_BY: - type = ATK_RELATION_LABELLED_BY; - break; - - case accessibility::AccessibleRelationType::MEMBER_OF: - type = ATK_RELATION_MEMBER_OF; - break; - - case accessibility::AccessibleRelationType::SUB_WINDOW_OF: - type = ATK_RELATION_SUBWINDOW_OF; - break; - - case accessibility::AccessibleRelationType::NODE_CHILD_OF: - type = ATK_RELATION_NODE_CHILD_OF; - break; - - default: - break; - } - - return type; -} - -AtkStateType mapAtkState( sal_Int16 nState ) -{ - AtkStateType type = ATK_STATE_INVALID; - - // A perfect / complete mapping ... - switch( nState ) - { -#define MAP_DIRECT( a ) \ - case accessibility::AccessibleStateType::a: \ - type = ATK_STATE_##a; break - - MAP_DIRECT( INVALID ); - MAP_DIRECT( ACTIVE ); - MAP_DIRECT( ARMED ); - MAP_DIRECT( BUSY ); - MAP_DIRECT( CHECKED ); - MAP_DIRECT( EDITABLE ); - MAP_DIRECT( ENABLED ); - MAP_DIRECT( EXPANDABLE ); - MAP_DIRECT( EXPANDED ); - MAP_DIRECT( FOCUSABLE ); - MAP_DIRECT( FOCUSED ); - MAP_DIRECT( HORIZONTAL ); - MAP_DIRECT( ICONIFIED ); - MAP_DIRECT( INDETERMINATE ); - MAP_DIRECT( MANAGES_DESCENDANTS ); - MAP_DIRECT( MODAL ); - MAP_DIRECT( MULTI_LINE ); - MAP_DIRECT( OPAQUE ); - MAP_DIRECT( PRESSED ); - MAP_DIRECT( RESIZABLE ); - MAP_DIRECT( SELECTABLE ); - MAP_DIRECT( SELECTED ); - MAP_DIRECT( SENSITIVE ); - MAP_DIRECT( SHOWING ); - MAP_DIRECT( SINGLE_LINE ); - MAP_DIRECT( STALE ); - MAP_DIRECT( TRANSIENT ); - MAP_DIRECT( VERTICAL ); - MAP_DIRECT( VISIBLE ); - MAP_DIRECT( DEFAULT ); - // a spelling error ... - case accessibility::AccessibleStateType::DEFUNC: - type = ATK_STATE_DEFUNCT; break; - case accessibility::AccessibleStateType::MULTI_SELECTABLE: - type = ATK_STATE_MULTISELECTABLE; break; - default: - //Mis-use ATK_STATE_LAST_DEFINED to check if a state is unmapped - //NOTE! Do not report it - type = ATK_STATE_LAST_DEFINED; - break; - } - - return type; -} - -static AtkRole getRoleForName( const gchar * name ) -{ - AtkRole ret = atk_role_for_name( name ); - if( ATK_ROLE_INVALID == ret ) - { - // this should only happen in old ATK versions - SAL_WNODEPRECATED_DECLARATIONS_PUSH - ret = atk_role_register( name ); - SAL_WNODEPRECATED_DECLARATIONS_POP - } - - return ret; -} - -static AtkRole mapToAtkRole( sal_Int16 nRole ) -{ - AtkRole role = ATK_ROLE_UNKNOWN; - - static AtkRole roleMap[] = { - ATK_ROLE_UNKNOWN, - ATK_ROLE_ALERT, - ATK_ROLE_COLUMN_HEADER, - ATK_ROLE_CANVAS, - ATK_ROLE_CHECK_BOX, - ATK_ROLE_CHECK_MENU_ITEM, - ATK_ROLE_COLOR_CHOOSER, - ATK_ROLE_COMBO_BOX, - ATK_ROLE_DATE_EDITOR, - ATK_ROLE_DESKTOP_ICON, - ATK_ROLE_DESKTOP_FRAME, // ? pane - ATK_ROLE_DIRECTORY_PANE, - ATK_ROLE_DIALOG, - ATK_ROLE_UNKNOWN, // DOCUMENT - registered below - ATK_ROLE_UNKNOWN, // EMBEDDED_OBJECT - registered below - ATK_ROLE_UNKNOWN, // END_NOTE - registered below - ATK_ROLE_FILE_CHOOSER, - ATK_ROLE_FILLER, - ATK_ROLE_FONT_CHOOSER, - ATK_ROLE_FOOTER, - ATK_ROLE_UNKNOWN, // FOOTNOTE - registered below - ATK_ROLE_FRAME, - ATK_ROLE_GLASS_PANE, - ATK_ROLE_IMAGE, // GRAPHIC - ATK_ROLE_UNKNOWN, // GROUP_BOX - registered below - ATK_ROLE_HEADER, - ATK_ROLE_HEADING, - ATK_ROLE_TEXT, // HYPER_LINK - registered below - ATK_ROLE_ICON, - ATK_ROLE_INTERNAL_FRAME, - ATK_ROLE_LABEL, - ATK_ROLE_LAYERED_PANE, - ATK_ROLE_LIST, - ATK_ROLE_LIST_ITEM, - ATK_ROLE_MENU, - ATK_ROLE_MENU_BAR, - ATK_ROLE_MENU_ITEM, - ATK_ROLE_OPTION_PANE, - ATK_ROLE_PAGE_TAB, - ATK_ROLE_PAGE_TAB_LIST, - ATK_ROLE_PANEL, - ATK_ROLE_PARAGRAPH, - ATK_ROLE_PASSWORD_TEXT, - ATK_ROLE_POPUP_MENU, - ATK_ROLE_PUSH_BUTTON, - ATK_ROLE_PROGRESS_BAR, - ATK_ROLE_RADIO_BUTTON, - ATK_ROLE_RADIO_MENU_ITEM, - ATK_ROLE_ROW_HEADER, - ATK_ROLE_ROOT_PANE, - ATK_ROLE_SCROLL_BAR, - ATK_ROLE_SCROLL_PANE, - ATK_ROLE_PANEL, // SHAPE - ATK_ROLE_SEPARATOR, - ATK_ROLE_SLIDER, - ATK_ROLE_SPIN_BUTTON, // SPIN_BOX ? - ATK_ROLE_SPLIT_PANE, - ATK_ROLE_STATUSBAR, - ATK_ROLE_TABLE, - ATK_ROLE_TABLE_CELL, - ATK_ROLE_TEXT, - ATK_ROLE_PANEL, // TEXT_FRAME - ATK_ROLE_TOGGLE_BUTTON, - ATK_ROLE_TOOL_BAR, - ATK_ROLE_TOOL_TIP, - ATK_ROLE_TREE, - ATK_ROLE_VIEWPORT, - ATK_ROLE_WINDOW, - ATK_ROLE_PUSH_BUTTON, // BUTTON_DROPDOWN - ATK_ROLE_PUSH_BUTTON, // BUTTON_MENU - ATK_ROLE_UNKNOWN, // CAPTION - registered below - ATK_ROLE_UNKNOWN, // CHART - registered below - ATK_ROLE_UNKNOWN, // EDIT_BAR - registered below - ATK_ROLE_UNKNOWN, // FORM - registered below - ATK_ROLE_UNKNOWN, // IMAGE_MAP - registered below - ATK_ROLE_UNKNOWN, // NOTE - registered below - ATK_ROLE_UNKNOWN, // PAGE - registered below - ATK_ROLE_RULER, - ATK_ROLE_UNKNOWN, // SECTION - registered below - ATK_ROLE_UNKNOWN, // TREE_ITEM - registered below - ATK_ROLE_TREE_TABLE, - ATK_ROLE_SCROLL_PANE, // COMMENT - mapped to atk_role_scroll_pane - ATK_ROLE_UNKNOWN // COMMENT_END - mapped to atk_role_unknown -#if defined(ATK_CHECK_VERSION) - //older ver that doesn't define ATK_CHECK_VERSION doesn't have the following - , ATK_ROLE_DOCUMENT_PRESENTATION - , ATK_ROLE_DOCUMENT_SPREADSHEET - , ATK_ROLE_DOCUMENT_TEXT -#if ATK_CHECK_VERSION(2,15,2) - , ATK_ROLE_STATIC -#else - , ATK_ROLE_LABEL -#endif -#else - //older version should fallback to DOCUMENT_FRAME role - , ATK_ROLE_DOCUMENT_FRAME - , ATK_ROLE_DOCUMENT_FRAME - , ATK_ROLE_DOCUMENT_FRAME - , ATK_ROLE_LABEL -#endif - }; - - static bool initialized = false; - - if( ! initialized ) - { - // the accessible roles below were added to ATK in later versions, - // with role_for_name we will know if they exist in runtime. - roleMap[accessibility::AccessibleRole::EDIT_BAR] = getRoleForName("edit bar"); - roleMap[accessibility::AccessibleRole::EMBEDDED_OBJECT] = getRoleForName("embedded"); - roleMap[accessibility::AccessibleRole::CHART] = getRoleForName("chart"); - roleMap[accessibility::AccessibleRole::CAPTION] = getRoleForName("caption"); - roleMap[accessibility::AccessibleRole::DOCUMENT] = getRoleForName("document frame"); - roleMap[accessibility::AccessibleRole::PAGE] = getRoleForName("page"); - roleMap[accessibility::AccessibleRole::SECTION] = getRoleForName("section"); - roleMap[accessibility::AccessibleRole::FORM] = getRoleForName("form"); - roleMap[accessibility::AccessibleRole::GROUP_BOX] = getRoleForName("grouping"); - roleMap[accessibility::AccessibleRole::COMMENT] = getRoleForName("comment"); - roleMap[accessibility::AccessibleRole::IMAGE_MAP] = getRoleForName("image map"); - roleMap[accessibility::AccessibleRole::TREE_ITEM] = getRoleForName("tree item"); - roleMap[accessibility::AccessibleRole::HYPER_LINK] = getRoleForName("link"); - roleMap[accessibility::AccessibleRole::END_NOTE] = getRoleForName("footnote"); - roleMap[accessibility::AccessibleRole::FOOTNOTE] = getRoleForName("footnote"); - roleMap[accessibility::AccessibleRole::NOTE] = getRoleForName("comment"); - - initialized = true; - } - - static const sal_Int32 nMapSize = SAL_N_ELEMENTS(roleMap); - if( 0 <= nRole && nMapSize > nRole ) - role = roleMap[nRole]; - - return role; -} - -/*****************************************************************************/ - -extern "C" { - -/*****************************************************************************/ - -static const gchar* -wrapper_get_name( AtkObject *atk_obj ) -{ - AtkObjectWrapper *obj = ATK_OBJECT_WRAPPER (atk_obj); - - if( obj->mpContext.is() ) - { - try { - OString aName = - OUStringToOString( - obj->mpContext->getAccessibleName(), - RTL_TEXTENCODING_UTF8); - - int nCmp = atk_obj->name ? rtl_str_compare( atk_obj->name, aName.getStr() ) : -1; - if( nCmp != 0 ) - { - if( atk_obj->name ) - g_free(atk_obj->name); - atk_obj->name = g_strdup(aName.getStr()); - } - } - catch(const uno::Exception&) { - g_warning( "Exception in getAccessibleName()" ); - } - } - - return ATK_OBJECT_CLASS (parent_class)->get_name(atk_obj); -} - -/*****************************************************************************/ - -static const gchar* -wrapper_get_description( AtkObject *atk_obj ) -{ - AtkObjectWrapper *obj = ATK_OBJECT_WRAPPER (atk_obj); - - if( obj->mpContext.is() ) - { - try { - OString aDescription = - OUStringToOString( - obj->mpContext->getAccessibleDescription(), - RTL_TEXTENCODING_UTF8); - - g_free(atk_obj->description); - atk_obj->description = g_strdup(aDescription.getStr()); - } - catch(const uno::Exception&) { - g_warning( "Exception in getAccessibleDescription()" ); - } - } - - return ATK_OBJECT_CLASS (parent_class)->get_description(atk_obj); - -} - -/*****************************************************************************/ - -static AtkAttributeSet * -wrapper_get_attributes( AtkObject *atk_obj ) -{ - AtkObjectWrapper *obj = ATK_OBJECT_WRAPPER( atk_obj ); - AtkAttributeSet *pSet = nullptr; - - try - { - uno::Reference< accessibility::XAccessibleExtendedAttributes > - xExtendedAttrs( obj->mpContext, uno::UNO_QUERY ); - if( xExtendedAttrs.is() ) - pSet = attribute_set_new_from_extended_attributes( xExtendedAttrs ); - } - catch(const uno::Exception&) - { - g_warning( "Exception in getAccessibleAttributes()" ); - } - - return pSet; -} - -/*****************************************************************************/ - -static gint -wrapper_get_n_children( AtkObject *atk_obj ) -{ - AtkObjectWrapper *obj = ATK_OBJECT_WRAPPER (atk_obj); - gint n = 0; - - if( obj->mpContext.is() ) - { - try { - n = obj->mpContext->getAccessibleChildCount(); - } - catch(const uno::Exception&) { - OSL_FAIL("Exception in getAccessibleChildCount()" ); - } - } - - return n; -} - -/*****************************************************************************/ - -static AtkObject * -wrapper_ref_child( AtkObject *atk_obj, - gint i ) -{ - AtkObjectWrapper *obj = ATK_OBJECT_WRAPPER (atk_obj); - AtkObject* child = nullptr; - - // see comments above atk_object_wrapper_remove_child - if( -1 < i && obj->index_of_child_about_to_be_removed == i ) - { - g_object_ref( obj->child_about_to_be_removed ); - return obj->child_about_to_be_removed; - } - - if( obj->mpContext.is() ) - { - try { - uno::Reference< accessibility::XAccessible > xAccessible = - obj->mpContext->getAccessibleChild( i ); - - child = atk_object_wrapper_ref( xAccessible ); - } - catch(const uno::Exception&) { - OSL_FAIL("Exception in getAccessibleChild"); - } - } - - return child; -} - -/*****************************************************************************/ - -static gint -wrapper_get_index_in_parent( AtkObject *atk_obj ) -{ - AtkObjectWrapper *obj = ATK_OBJECT_WRAPPER (atk_obj); - - //if we're a native GtkDrawingArea with custom a11y, use the default toolkit a11y - if (obj->mpOrig) - return atk_object_get_index_in_parent(obj->mpOrig); - - gint i = -1; - - if( obj->mpContext.is() ) - { - try { - i = obj->mpContext->getAccessibleIndexInParent(); - } - catch(const uno::Exception&) { - g_warning( "Exception in getAccessibleIndexInParent()" ); - } - } - return i; -} - -/*****************************************************************************/ - -AtkRelation* -atk_object_wrapper_relation_new(const accessibility::AccessibleRelation& rRelation) -{ - sal_uInt32 nTargetCount = rRelation.TargetSet.getLength(); - - std::vector<AtkObject*> aTargets; - - for (const auto& rTarget : rRelation.TargetSet) - { - uno::Reference< accessibility::XAccessible > xAccessible( rTarget, uno::UNO_QUERY ); - aTargets.push_back(atk_object_wrapper_ref(xAccessible)); - } - - AtkRelation *pRel = - atk_relation_new( - aTargets.data(), nTargetCount, - mapRelationType( rRelation.RelationType ) - ); - - return pRel; -} - -static AtkRelationSet * -wrapper_ref_relation_set( AtkObject *atk_obj ) -{ - AtkObjectWrapper *obj = ATK_OBJECT_WRAPPER (atk_obj); - - //if we're a native GtkDrawingArea with custom a11y, use the default toolkit relation set impl - if (obj->mpOrig) - return atk_object_ref_relation_set(obj->mpOrig); - - AtkRelationSet *pSet = atk_relation_set_new(); - - if( obj->mpContext.is() ) - { - try { - uno::Reference< accessibility::XAccessibleRelationSet > xRelationSet( - obj->mpContext->getAccessibleRelationSet() - ); - - sal_Int32 nRelations = xRelationSet.is() ? xRelationSet->getRelationCount() : 0; - for( sal_Int32 n = 0; n < nRelations; n++ ) - { - AtkRelation *pRel = atk_object_wrapper_relation_new(xRelationSet->getRelation(n)); - atk_relation_set_add(pSet, pRel); - g_object_unref(pRel); - } - } - catch(const uno::Exception &) { - g_object_unref( G_OBJECT( pSet ) ); - pSet = nullptr; - } - } - - return pSet; -} - -static AtkStateSet * -wrapper_ref_state_set( AtkObject *atk_obj ) -{ - AtkObjectWrapper *obj = ATK_OBJECT_WRAPPER (atk_obj); - AtkStateSet *pSet = atk_state_set_new(); - - if( obj->mpContext.is() ) - { - try { - uno::Reference< accessibility::XAccessibleStateSet > xStateSet( - obj->mpContext->getAccessibleStateSet()); - - if( xStateSet.is() ) - { - uno::Sequence< sal_Int16 > aStates = xStateSet->getStates(); - - for( const auto nState : aStates ) - { - // ATK_STATE_LAST_DEFINED is used to check if the state - // is unmapped, do not report it to Atk - if ( mapAtkState( nState ) != ATK_STATE_LAST_DEFINED ) - atk_state_set_add_state( pSet, mapAtkState( nState ) ); - } - - // We need to emulate FOCUS state for menus, menu-items etc. - if( atk_obj == atk_get_focus_object() ) - atk_state_set_add_state( pSet, ATK_STATE_FOCUSED ); -/* FIXME - should we do this ? - else - atk_state_set_remove_state( pSet, ATK_STATE_FOCUSED ); -*/ - } - } - - catch(const uno::Exception &) { - g_warning( "Exception in wrapper_ref_state_set" ); - atk_state_set_add_state( pSet, ATK_STATE_DEFUNCT ); - } - } - else - atk_state_set_add_state( pSet, ATK_STATE_DEFUNCT ); - - return pSet; -} - -/*****************************************************************************/ - -static void -atk_object_wrapper_finalize (GObject *obj) -{ - AtkObjectWrapper *pWrap = ATK_OBJECT_WRAPPER (obj); - - if( pWrap->mpAccessible.is() ) - { - ooo_wrapper_registry_remove( pWrap->mpAccessible ); - pWrap->mpAccessible.clear(); - } - - atk_object_wrapper_dispose( pWrap ); - - parent_class->finalize( obj ); -} - -static void -atk_object_wrapper_class_init (AtkObjectWrapperClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS( klass ); - AtkObjectClass *atk_class = ATK_OBJECT_CLASS( klass ); - - parent_class = static_cast<GObjectClass *>(g_type_class_peek_parent (klass)); - - // GObject methods - gobject_class->finalize = atk_object_wrapper_finalize; - - // AtkObject methods - atk_class->get_name = wrapper_get_name; - atk_class->get_description = wrapper_get_description; - atk_class->get_attributes = wrapper_get_attributes; - atk_class->get_n_children = wrapper_get_n_children; - atk_class->ref_child = wrapper_ref_child; - atk_class->get_index_in_parent = wrapper_get_index_in_parent; - atk_class->ref_relation_set = wrapper_ref_relation_set; - atk_class->ref_state_set = wrapper_ref_state_set; -} - -static void -atk_object_wrapper_init (AtkObjectWrapper *wrapper, - AtkObjectWrapperClass*) -{ - wrapper->mpAction = nullptr; - wrapper->mpComponent = nullptr; - wrapper->mpEditableText = nullptr; - wrapper->mpHypertext = nullptr; - wrapper->mpImage = nullptr; - wrapper->mpSelection = nullptr; - wrapper->mpTable = nullptr; - wrapper->mpText = nullptr; - wrapper->mpValue = nullptr; -} - -} // extern "C" - -GType -atk_object_wrapper_get_type() -{ - static GType type = 0; - - if (!type) - { - static const GTypeInfo typeInfo = - { - sizeof (AtkObjectWrapperClass), - nullptr, - nullptr, - reinterpret_cast<GClassInitFunc>(atk_object_wrapper_class_init), - nullptr, - nullptr, - sizeof (AtkObjectWrapper), - 0, - reinterpret_cast<GInstanceInitFunc>(atk_object_wrapper_init), - nullptr - } ; - type = g_type_register_static (ATK_TYPE_OBJECT, - "OOoAtkObj", - &typeInfo, GTypeFlags(0)) ; - } - return type; -} - -static bool -isOfType( uno::XInterface *pInterface, const uno::Type & rType ) -{ - g_return_val_if_fail( pInterface != nullptr, false ); - - bool bIs = false; - try { - uno::Any aRet = pInterface->queryInterface( rType ); - - bIs = ( ( typelib_TypeClass_INTERFACE == aRet.pType->eTypeClass ) && - ( aRet.pReserved != nullptr ) ); - } catch( const uno::Exception &) { } - - return bIs; -} - -extern "C" { -typedef GType (* GetGIfaceType ) (); -} -const struct { - const char *name; - GInterfaceInitFunc const aInit; - GetGIfaceType const aGetGIfaceType; - const uno::Type & (*aGetUnoType) (); -} aTypeTable[] = { -// re-location heaven: - { - "Comp", reinterpret_cast<GInterfaceInitFunc>(componentIfaceInit), - atk_component_get_type, - cppu::UnoType<accessibility::XAccessibleComponent>::get - }, - { - "Act", reinterpret_cast<GInterfaceInitFunc>(actionIfaceInit), - atk_action_get_type, - cppu::UnoType<accessibility::XAccessibleAction>::get - }, - { - "Txt", reinterpret_cast<GInterfaceInitFunc>(textIfaceInit), - atk_text_get_type, - cppu::UnoType<accessibility::XAccessibleText>::get - }, - { - "Val", reinterpret_cast<GInterfaceInitFunc>(valueIfaceInit), - atk_value_get_type, - cppu::UnoType<accessibility::XAccessibleValue>::get - }, - { - "Tab", reinterpret_cast<GInterfaceInitFunc>(tableIfaceInit), - atk_table_get_type, - cppu::UnoType<accessibility::XAccessibleTable>::get - }, - { - "Edt", reinterpret_cast<GInterfaceInitFunc>(editableTextIfaceInit), - atk_editable_text_get_type, - cppu::UnoType<accessibility::XAccessibleEditableText>::get - }, - { - "Img", reinterpret_cast<GInterfaceInitFunc>(imageIfaceInit), - atk_image_get_type, - cppu::UnoType<accessibility::XAccessibleImage>::get - }, - { - "Hyp", reinterpret_cast<GInterfaceInitFunc>(hypertextIfaceInit), - atk_hypertext_get_type, - cppu::UnoType<accessibility::XAccessibleHypertext>::get - }, - { - "Sel", reinterpret_cast<GInterfaceInitFunc>(selectionIfaceInit), - atk_selection_get_type, - cppu::UnoType<accessibility::XAccessibleSelection>::get - } - // AtkDocument is a nastily broken interface (so far) - // we could impl. get_document_type perhaps though. -}; - -const int aTypeTableSize = G_N_ELEMENTS( aTypeTable ); - -static GType -ensureTypeFor( uno::XInterface *pAccessible ) -{ - int i; - bool bTypes[ aTypeTableSize ] = { false, }; - OStringBuffer aTypeNameBuf( "OOoAtkObj" ); - - for( i = 0; i < aTypeTableSize; i++ ) - { - if( isOfType( pAccessible, aTypeTable[i].aGetUnoType() ) ) - { - aTypeNameBuf.append(aTypeTable[i].name); - bTypes[i] = true; - } - } - - OString aTypeName = aTypeNameBuf.makeStringAndClear(); - GType nType = g_type_from_name( aTypeName.getStr() ); - if( nType == G_TYPE_INVALID ) - { - GTypeInfo aTypeInfo = { - sizeof( AtkObjectWrapperClass ), - nullptr, nullptr, nullptr, nullptr, nullptr, - sizeof( AtkObjectWrapper ), - 0, nullptr, nullptr - } ; - nType = g_type_register_static( ATK_TYPE_OBJECT_WRAPPER, - aTypeName.getStr(), &aTypeInfo, - GTypeFlags(0) ) ; - - for( int j = 0; j < aTypeTableSize; j++ ) - if( bTypes[j] ) - { - GInterfaceInfo aIfaceInfo = { nullptr, nullptr, nullptr }; - aIfaceInfo.interface_init = aTypeTable[j].aInit; - g_type_add_interface_static (nType, aTypeTable[j].aGetGIfaceType(), - &aIfaceInfo); - } - } - return nType; -} - -AtkObject * -atk_object_wrapper_ref( const uno::Reference< accessibility::XAccessible > &rxAccessible, bool create ) -{ - g_return_val_if_fail( rxAccessible.get() != nullptr, nullptr ); - - AtkObject *obj = ooo_wrapper_registry_get(rxAccessible); - if( obj ) - { - g_object_ref( obj ); - return obj; - } - - if( create ) - return atk_object_wrapper_new( rxAccessible ); - - return nullptr; -} - -AtkObject * -atk_object_wrapper_new( const css::uno::Reference< css::accessibility::XAccessible >& rxAccessible, - AtkObject* parent, AtkObject* orig ) -{ - g_return_val_if_fail( rxAccessible.get() != nullptr, nullptr ); - - AtkObjectWrapper *pWrap = nullptr; - - try { - uno::Reference< accessibility::XAccessibleContext > xContext(rxAccessible->getAccessibleContext()); - - g_return_val_if_fail( xContext.get() != nullptr, nullptr ); - - GType nType = ensureTypeFor( xContext.get() ); - gpointer obj = g_object_new( nType, nullptr); - - pWrap = ATK_OBJECT_WRAPPER( obj ); - pWrap->mpAccessible = rxAccessible; - - pWrap->index_of_child_about_to_be_removed = -1; - pWrap->child_about_to_be_removed = nullptr; - - pWrap->mpContext = xContext; - pWrap->mpOrig = orig; - - AtkObject* atk_obj = ATK_OBJECT(pWrap); - atk_obj->role = mapToAtkRole( xContext->getAccessibleRole() ); - atk_obj->accessible_parent = parent; - - ooo_wrapper_registry_add( rxAccessible, atk_obj ); - - if( parent ) - g_object_ref( atk_obj->accessible_parent ); - else - { - /* gail_focus_tracker remembers the focused object at the first - * parent in the hierarchy that is a Gtk+ widget, but at the time the - * event gets processed (at idle), it may be too late to create the - * hierarchy, so doing it now .. - */ - uno::Reference< accessibility::XAccessible > xParent( xContext->getAccessibleParent() ); - - if( xParent.is() ) - atk_obj->accessible_parent = atk_object_wrapper_ref( xParent ); - } - - // Attach a listener to the UNO object if it's not TRANSIENT - uno::Reference< accessibility::XAccessibleStateSet > xStateSet( xContext->getAccessibleStateSet() ); - if( xStateSet.is() && ! xStateSet->contains( accessibility::AccessibleStateType::TRANSIENT ) ) - { - uno::Reference< accessibility::XAccessibleEventBroadcaster > xBroadcaster(xContext, uno::UNO_QUERY); - if( xBroadcaster.is() ) - { - uno::Reference<accessibility::XAccessibleEventListener> xListener(new AtkListener(pWrap)); - xBroadcaster->addAccessibleEventListener(xListener); - } - else - OSL_ASSERT( false ); - } - -#if ATK_CHECK_VERSION(2,33,1) - { - css::uno::Reference<css::accessibility::XAccessibleContext2> xContext2(xContext, css::uno::UNO_QUERY); - if( xContext2.is() ) - { - OString aId = OUStringToOString( xContext2->getAccessibleId(), RTL_TEXTENCODING_UTF8); - atk_object_set_accessible_id(atk_obj, aId.getStr()); - } - } -#endif - - return ATK_OBJECT( pWrap ); - } - catch (const uno::Exception &) - { - if( pWrap ) - g_object_unref( pWrap ); - - return nullptr; - } -} - -/*****************************************************************************/ - -void atk_object_wrapper_add_child(AtkObjectWrapper* wrapper, AtkObject *child, gint index) -{ - AtkObject *atk_obj = ATK_OBJECT( wrapper ); - - atk_object_set_parent( child, atk_obj ); - g_signal_emit_by_name( atk_obj, "children_changed::add", index, child, nullptr ); -} - -/*****************************************************************************/ - -void atk_object_wrapper_remove_child(AtkObjectWrapper* wrapper, AtkObject *child, gint index) -{ - /* - * the atk-bridge GTK+ module gets back to the event source to ref the child just - * vanishing, so we keep this reference because the semantic on OOo side is different. - */ - wrapper->child_about_to_be_removed = child; - wrapper->index_of_child_about_to_be_removed = index; - - g_signal_emit_by_name( ATK_OBJECT( wrapper ), "children_changed::remove", index, child, nullptr ); - - wrapper->index_of_child_about_to_be_removed = -1; - wrapper->child_about_to_be_removed = nullptr; -} - -/*****************************************************************************/ - -void atk_object_wrapper_set_role(AtkObjectWrapper* wrapper, sal_Int16 role) -{ - AtkObject *atk_obj = ATK_OBJECT( wrapper ); - atk_object_set_role( atk_obj, mapToAtkRole( role ) ); -} - -/*****************************************************************************/ - -void atk_object_wrapper_dispose(AtkObjectWrapper* wrapper) -{ - wrapper->mpContext.clear(); - wrapper->mpAction.clear(); - wrapper->mpComponent.clear(); - wrapper->mpEditableText.clear(); - wrapper->mpHypertext.clear(); - wrapper->mpImage.clear(); - wrapper->mpSelection.clear(); - wrapper->mpMultiLineText.clear(); - wrapper->mpTable.clear(); - wrapper->mpText.clear(); - wrapper->mpTextMarkup.clear(); - wrapper->mpTextAttributes.clear(); - wrapper->mpValue.clear(); -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/gloactiongroup.cxx b/vcl/unx/gtk/gloactiongroup.cxx deleted file mode 100644 index 56782e2cd46f..000000000000 --- a/vcl/unx/gtk/gloactiongroup.cxx +++ /dev/null @@ -1,398 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -#include <unx/gtk/gtksalmenu.hxx> - -#ifdef ENABLE_GMENU_INTEGRATION - -#include <unx/gtk/gloactiongroup.h> -#include <unx/gtk/gtkinst.hxx> -#include <unx/gtk/gtkframe.hxx> - -#include <sal/log.hxx> - -/* - * GLOAction - */ - -#define G_TYPE_LO_ACTION (g_lo_action_get_type ()) -#define G_LO_ACTION(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ - G_TYPE_LO_ACTION, GLOAction)) - -struct GLOAction -{ - GObject parent_instance; - - gint item_id; // Menu item ID. - gboolean submenu; // TRUE if action is a submenu action. - gboolean enabled; // TRUE if action is enabled. - GVariantType* parameter_type; // A GVariantType with the action parameter type. - GVariantType* state_type; // A GVariantType with item state type - GVariant* state_hint; // A GVariant with state hints. - GVariant* state; // A GVariant with current item state -}; - -typedef GObjectClass GLOActionClass; - -#ifdef __GNUC__ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-function" -#endif -G_DEFINE_TYPE (GLOAction, g_lo_action, G_TYPE_OBJECT); -#ifdef __GNUC__ -#pragma GCC diagnostic pop -#endif - -static GLOAction* -g_lo_action_new() -{ - return G_LO_ACTION (g_object_new (G_TYPE_LO_ACTION, nullptr)); -} - -static void -g_lo_action_init (GLOAction *action) -{ - action->item_id = -1; - action->submenu = FALSE; - action->enabled = TRUE; - action->parameter_type = nullptr; - action->state_type = nullptr; - action->state_hint = nullptr; - action->state = nullptr; -} - -static void -g_lo_action_finalize (GObject *object) -{ - GLOAction* action = G_LO_ACTION(object); - - if (action->parameter_type) - g_variant_type_free (action->parameter_type); - - if (action->state_type) - g_variant_type_free (action->state_type); - - if (action->state_hint) - g_variant_unref (action->state_hint); - - if (action->state) - g_variant_unref (action->state); - - G_OBJECT_CLASS (g_lo_action_parent_class)->finalize (object); -} - -static void -g_lo_action_class_init (GLOActionClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS(klass); - - object_class->finalize = g_lo_action_finalize; -} - -/* - * GLOActionGroup - */ - -struct GLOActionGroupPrivate -{ - GHashTable *table; /* string -> GLOAction */ -}; - -static void g_lo_action_group_iface_init (GActionGroupInterface *); - -#ifdef __GNUC__ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-function" -#endif -G_DEFINE_TYPE_WITH_CODE (GLOActionGroup, - g_lo_action_group, G_TYPE_OBJECT, - G_ADD_PRIVATE(GLOActionGroup) - G_IMPLEMENT_INTERFACE (G_TYPE_ACTION_GROUP, - g_lo_action_group_iface_init)); -#ifdef __GNUC__ -#pragma GCC diagnostic pop -#endif - -static gchar ** -g_lo_action_group_list_actions (GActionGroup *group) -{ - GLOActionGroup *loGroup = G_LO_ACTION_GROUP (group); - GHashTableIter iter; - gint n, i = 0; - gchar **keys; - gpointer key; - - n = g_hash_table_size (loGroup->priv->table); - keys = g_new (gchar *, n + 1); - - g_hash_table_iter_init (&iter, loGroup->priv->table); - while (g_hash_table_iter_next (&iter, &key, nullptr)) - keys[i++] = g_strdup (static_cast<gchar*>(key)); - g_assert_cmpint (i, ==, n); - keys[n] = nullptr; - - return keys; -} - -static gboolean -g_lo_action_group_query_action (GActionGroup *group, - const gchar *action_name, - gboolean *enabled, - const GVariantType **parameter_type, - const GVariantType **state_type, - GVariant **state_hint, - GVariant **state) -{ - //SAL_INFO("vcl.unity", "g_lo_action_group_query_action on " << group); - GLOActionGroup *lo_group = G_LO_ACTION_GROUP (group); - GLOAction* action = G_LO_ACTION (g_hash_table_lookup (lo_group->priv->table, action_name)); - - if (action == nullptr) - return FALSE; - - if (enabled) - { - *enabled = action->enabled; - } - - if (parameter_type) - *parameter_type = action->parameter_type; - - if (state_type) - *state_type = action->state_type; - - if (state_hint) - *state_hint = (action->state_hint) ? g_variant_ref (action->state_hint) : nullptr; - - if (state) - *state = (action->state) ? g_variant_ref (action->state) : nullptr; - - return TRUE; -} - -static void -g_lo_action_group_perform_submenu_action (GLOActionGroup *group, - const gchar *action_name, - GVariant *state) -{ - gboolean bState = g_variant_get_boolean (state); - SAL_INFO("vcl.unity", "g_lo_action_group_perform_submenu_action on " << group << " to " << bState); - - if (bState) - GtkSalMenu::Activate(action_name); - else - GtkSalMenu::Deactivate(action_name); -} - -static void -g_lo_action_group_change_state (GActionGroup *group, - const gchar *action_name, - GVariant *value) -{ - SAL_INFO("vcl.unity", "g_lo_action_group_change_state on " << group ); - g_return_if_fail (value != nullptr); - - g_variant_ref_sink (value); - - if (action_name != nullptr) - { - GLOActionGroup* lo_group = G_LO_ACTION_GROUP (group); - GLOAction* action = G_LO_ACTION (g_hash_table_lookup (lo_group->priv->table, action_name)); - - if (action != nullptr) - { - if (action->submenu) - g_lo_action_group_perform_submenu_action (lo_group, action_name, value); - else - { - gboolean is_new = FALSE; - - /* If action already exists but has no state, it should be removed and added again. */ - if (action->state_type == nullptr) - { - g_action_group_action_removed (G_ACTION_GROUP (group), action_name); - action->state_type = g_variant_type_copy (g_variant_get_type(value)); - is_new = TRUE; - } - - if (g_variant_is_of_type (value, action->state_type)) - { - if (action->state) - g_variant_unref(action->state); - - action->state = g_variant_ref (value); - - if (is_new) - g_action_group_action_added (G_ACTION_GROUP (group), action_name); - else - g_action_group_action_state_changed (group, action_name, value); - } - } - } - } - - g_variant_unref (value); -} - -static void -g_lo_action_group_activate (GActionGroup *group, - const gchar *action_name, - GVariant *parameter) -{ - if (parameter != nullptr) - g_action_group_change_action_state(group, action_name, parameter); - GtkSalMenu::DispatchCommand(action_name); -} - -void -g_lo_action_group_insert (GLOActionGroup *group, - const gchar *action_name, - gint item_id, - gboolean submenu) -{ - g_lo_action_group_insert_stateful (group, action_name, item_id, submenu, nullptr, nullptr, nullptr, nullptr); -} - -void -g_lo_action_group_insert_stateful (GLOActionGroup *group, - const gchar *action_name, - gint item_id, - gboolean submenu, - const GVariantType *parameter_type, - const GVariantType *state_type, - GVariant *state_hint, - GVariant *state) -{ - g_return_if_fail (G_IS_LO_ACTION_GROUP (group)); - - GLOAction* old_action = G_LO_ACTION (g_hash_table_lookup (group->priv->table, action_name)); - - if (old_action == nullptr || old_action->item_id != item_id) - { - if (old_action != nullptr) - g_lo_action_group_remove (group, action_name); - - GLOAction* action = g_lo_action_new(); - - g_hash_table_insert (group->priv->table, g_strdup (action_name), action); - - action->item_id = item_id; - action->submenu = submenu; - - if (parameter_type) - action->parameter_type = const_cast<GVariantType*>(parameter_type); - - if (state_type) - action->state_type = const_cast<GVariantType*>(state_type); - - if (state_hint) - action->state_hint = g_variant_ref_sink (state_hint); - - if (state) - action->state = g_variant_ref_sink (state); - - g_action_group_action_added (G_ACTION_GROUP (group), action_name); - } -} - -static void -g_lo_action_group_finalize (GObject *object) -{ - GLOActionGroup *lo_group = G_LO_ACTION_GROUP (object); - - g_hash_table_unref (lo_group->priv->table); - - G_OBJECT_CLASS (g_lo_action_group_parent_class)->finalize (object); -} - -static void -g_lo_action_group_init (GLOActionGroup *group) -{ - SAL_INFO("vcl.unity", "g_lo_action_group_init on " << group); - group->priv = static_cast<GLOActionGroupPrivate *>(g_lo_action_group_get_instance_private (group)); - group->priv->table = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, g_object_unref); -} - -static void -g_lo_action_group_class_init (GLOActionGroupClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = g_lo_action_group_finalize; -} - -static void -g_lo_action_group_iface_init (GActionGroupInterface *iface) -{ - iface->list_actions = g_lo_action_group_list_actions; - iface->query_action = g_lo_action_group_query_action; - iface->change_action_state = g_lo_action_group_change_state; - iface->activate_action = g_lo_action_group_activate; -} - -GLOActionGroup * -g_lo_action_group_new() -{ - GLOActionGroup* group = G_LO_ACTION_GROUP (g_object_new (G_TYPE_LO_ACTION_GROUP, nullptr)); - return group; -} - -void -g_lo_action_group_set_action_enabled (GLOActionGroup *group, - const gchar *action_name, - gboolean enabled) -{ - SAL_INFO("vcl.unity", "g_lo_action_group_set_action_enabled on " << group); - g_return_if_fail (G_IS_LO_ACTION_GROUP (group)); - g_return_if_fail (action_name != nullptr); - - GLOAction* action = G_LO_ACTION (g_hash_table_lookup (group->priv->table, action_name)); - - if (action == nullptr) - return; - - action->enabled = enabled; - - g_action_group_action_enabled_changed (G_ACTION_GROUP (group), action_name, enabled); -} - -void -g_lo_action_group_remove (GLOActionGroup *group, - const gchar *action_name) -{ - SAL_INFO("vcl.unity", "g_lo_action_group_remove on " << group); - g_return_if_fail (G_IS_LO_ACTION_GROUP (group)); - - if (action_name != nullptr) - { - g_action_group_action_removed (G_ACTION_GROUP (group), action_name); - g_hash_table_remove (group->priv->table, action_name); - } -} - -void -g_lo_action_group_clear (GLOActionGroup *group) -{ - SAL_INFO("vcl.unity", "g_lo_action_group_clear on " << group); - g_return_if_fail (G_IS_LO_ACTION_GROUP (group)); - - GList* keys = g_hash_table_get_keys (group->priv->table); - - for (GList* element = g_list_first (keys); element != nullptr; element = g_list_next (element)) - { - g_lo_action_group_remove (group, static_cast<gchar*>(element->data)); - } - - g_list_free (keys); -} - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/glomenu.cxx b/vcl/unx/gtk/glomenu.cxx deleted file mode 100644 index 5457ac6eaa05..000000000000 --- a/vcl/unx/gtk/glomenu.cxx +++ /dev/null @@ -1,691 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -#include <string.h> - -#include <unx/gtk/gtksalmenu.hxx> - -#ifdef ENABLE_GMENU_INTEGRATION - -#include <unx/gtk/glomenu.h> - -struct GLOMenu -{ - GMenuModel const parent_instance; - - GArray *items; -}; - -typedef GMenuModelClass GLOMenuClass; - -#ifdef __GNUC__ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-function" -#endif -G_DEFINE_TYPE (GLOMenu, g_lo_menu, G_TYPE_MENU_MODEL); -#ifdef __GNUC__ -#pragma GCC diagnostic pop -#endif - -struct item -{ - GHashTable* attributes; // Item attributes. - GHashTable* links; // Item links. -}; - -static void -g_lo_menu_struct_item_init (struct item *menu_item) -{ - menu_item->attributes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, reinterpret_cast<GDestroyNotify>(g_variant_unref)); - menu_item->links = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); -} - -/* We treat attribute names the same as GSettings keys: - * - only lowercase ascii, digits and '-' - * - must start with lowercase - * - must not end with '-' - * - no consecutive '-' - * - not longer than 1024 chars - */ -static gboolean -valid_attribute_name (const gchar *name) -{ - gint i; - - if (!g_ascii_islower (name[0])) - return FALSE; - - for (i = 1; name[i]; i++) - { - if (name[i] != '-' && - !g_ascii_islower (name[i]) && - !g_ascii_isdigit (name[i])) - return FALSE; - - if (name[i] == '-' && name[i + 1] == '-') - return FALSE; - } - - if (name[i - 1] == '-') - return FALSE; - - if (i > 1024) - return FALSE; - - return TRUE; -} - -/* - * GLOMenu - */ - -static gboolean -g_lo_menu_is_mutable (GMenuModel*) -{ - // Menu is always mutable. - return TRUE; -} - -static gint -g_lo_menu_get_n_items (GMenuModel *model) -{ - g_return_val_if_fail (model != nullptr, 0); - GLOMenu *menu = G_LO_MENU (model); - g_return_val_if_fail (menu->items != nullptr, 0); - - return menu->items->len; -} - -gint -g_lo_menu_get_n_items_from_section (GLOMenu *menu, - gint section) -{ - g_return_val_if_fail (0 <= section && section < static_cast<gint>(menu->items->len), 0); - - GLOMenu *model = g_lo_menu_get_section (menu, section); - - g_return_val_if_fail (model != nullptr, 0); - - gint length = model->items->len; - - g_object_unref (model); - - return length; -} - -static void -g_lo_menu_get_item_attributes (GMenuModel *model, - gint position, - GHashTable **table) -{ - GLOMenu *menu = G_LO_MENU (model); - *table = g_hash_table_ref (g_array_index (menu->items, struct item, position).attributes); -} - -static void -g_lo_menu_get_item_links (GMenuModel *model, - gint position, - GHashTable **table) -{ - GLOMenu *menu = G_LO_MENU (model); - *table = g_hash_table_ref (g_array_index (menu->items, struct item, position).links); -} - -void -g_lo_menu_insert (GLOMenu *menu, - gint position, - const gchar *label) -{ - g_lo_menu_insert_section (menu, position, label, nullptr); -} - -void -g_lo_menu_insert_in_section (GLOMenu *menu, - gint section, - gint position, - const gchar *label) -{ - g_return_if_fail (G_IS_LO_MENU (menu)); - g_return_if_fail (0 <= section && section < static_cast<gint>(menu->items->len)); - - GLOMenu *model = g_lo_menu_get_section (menu, section); - - g_return_if_fail (model != nullptr); - - g_lo_menu_insert (model, position, label); - - g_object_unref (model); -} - -GLOMenu * -g_lo_menu_new() -{ - return G_LO_MENU( g_object_new (G_TYPE_LO_MENU, nullptr) ); -} - -static void -g_lo_menu_set_attribute_value (GLOMenu *menu, - gint position, - const gchar *attribute, - GVariant *value) -{ - g_return_if_fail (G_IS_LO_MENU (menu)); - g_return_if_fail (attribute != nullptr); - g_return_if_fail (valid_attribute_name (attribute)); - - if (position >= static_cast<gint>(menu->items->len)) - return; - - struct item menu_item = g_array_index (menu->items, struct item, position); - - if (value != nullptr) - g_hash_table_insert (menu_item.attributes, g_strdup (attribute), g_variant_ref_sink (value)); - else - g_hash_table_remove (menu_item.attributes, attribute); -} - -static GVariant* -g_lo_menu_get_attribute_value_from_item_in_section (GLOMenu *menu, - gint section, - gint position, - const gchar *attribute, - const GVariantType *type) -{ - GMenuModel *model = G_MENU_MODEL (g_lo_menu_get_section (menu, section)); - - g_return_val_if_fail (model != nullptr, nullptr); - - GVariant *value = g_menu_model_get_item_attribute_value (model, - position, - attribute, - type); - - g_object_unref (model); - - return value; -} - -void -g_lo_menu_set_label (GLOMenu *menu, - gint position, - const gchar *label) -{ - g_return_if_fail (G_IS_LO_MENU (menu)); - - GVariant *value; - - if (label != nullptr) - value = g_variant_new_string (label); - else - value = nullptr; - - g_lo_menu_set_attribute_value (menu, position, G_MENU_ATTRIBUTE_LABEL, value); -} - -void -g_lo_menu_set_icon (GLOMenu *menu, - gint position, - const GIcon *icon) -{ - g_return_if_fail (G_IS_LO_MENU (menu)); - - GVariant *value; - - if (icon != nullptr) - { -#if GLIB_CHECK_VERSION(2,38,0) - value = g_icon_serialize (const_cast<GIcon*>(icon)); -#else - value = nullptr; -#endif - } - else - value = nullptr; - -#ifndef G_MENU_ATTRIBUTE_ICON -# define G_MENU_ATTRIBUTE_ICON "icon" -#endif - - g_lo_menu_set_attribute_value (menu, position, G_MENU_ATTRIBUTE_ICON, value); - if (value) - g_variant_unref (value); -} - -void -g_lo_menu_set_label_to_item_in_section (GLOMenu *menu, - gint section, - gint position, - const gchar *label) -{ - g_return_if_fail (G_IS_LO_MENU (menu)); - - GLOMenu *model = g_lo_menu_get_section (menu, section); - - g_return_if_fail (model != nullptr); - - g_lo_menu_set_label (model, position, label); - - // Notify the update. - g_menu_model_items_changed (G_MENU_MODEL (model), position, 1, 1); - - g_object_unref (model); -} - -void -g_lo_menu_set_icon_to_item_in_section (GLOMenu *menu, - gint section, - gint position, - const GIcon *icon) -{ - g_return_if_fail (G_IS_LO_MENU (menu)); - - GLOMenu *model = g_lo_menu_get_section (menu, section); - - g_return_if_fail (model != nullptr); - - g_lo_menu_set_icon (model, position, icon); - - // Notify the update. - g_menu_model_items_changed (G_MENU_MODEL (model), position, 1, 1); - - g_object_unref (model); -} - -gchar * -g_lo_menu_get_label_from_item_in_section (GLOMenu *menu, - gint section, - gint position) -{ - g_return_val_if_fail (G_IS_LO_MENU (menu), nullptr); - - GVariant *label_value = g_lo_menu_get_attribute_value_from_item_in_section (menu, - section, - position, - G_MENU_ATTRIBUTE_LABEL, - G_VARIANT_TYPE_STRING); - - gchar *label = nullptr; - - if (label_value) - { - label = g_variant_dup_string (label_value, nullptr); - g_variant_unref (label_value); - } - - return label; -} - -void -g_lo_menu_set_action_and_target_value (GLOMenu *menu, - gint position, - const gchar *action, - GVariant *target_value) -{ - g_return_if_fail (G_IS_LO_MENU (menu)); - - GVariant *action_value; - - if (action != nullptr) - { - action_value = g_variant_new_string (action); - } - else - { - action_value = nullptr; - target_value = nullptr; - } - - g_lo_menu_set_attribute_value (menu, position, G_MENU_ATTRIBUTE_ACTION, action_value); - g_lo_menu_set_attribute_value (menu, position, G_MENU_ATTRIBUTE_TARGET, target_value); - g_lo_menu_set_attribute_value (menu, position, G_LO_MENU_ATTRIBUTE_SUBMENU_ACTION, nullptr); - - g_menu_model_items_changed (G_MENU_MODEL (menu), position, 1, 1); -} - -void -g_lo_menu_set_action_and_target_value_to_item_in_section (GLOMenu *menu, - gint section, - gint position, - const gchar *command, - GVariant *target_value) -{ - g_return_if_fail (G_IS_LO_MENU (menu)); - - GLOMenu *model = g_lo_menu_get_section (menu, section); - - g_return_if_fail (model != nullptr); - - g_lo_menu_set_action_and_target_value (model, position, command, target_value); - - g_object_unref (model); -} - -void -g_lo_menu_set_accelerator_to_item_in_section (GLOMenu *menu, - gint section, - gint position, - const gchar *accelerator) -{ - g_return_if_fail (G_IS_LO_MENU (menu)); - - GLOMenu *model = g_lo_menu_get_section (menu, section); - - g_return_if_fail (model != nullptr); - - GVariant *value; - - if (accelerator != nullptr) - value = g_variant_new_string (accelerator); - else - value = nullptr; - - g_lo_menu_set_attribute_value (model, position, G_LO_MENU_ATTRIBUTE_ACCELERATOR, value); - - // Notify the update. - g_menu_model_items_changed (G_MENU_MODEL (model), position, 1, 1); - - g_object_unref (model); -} - -gchar * -g_lo_menu_get_accelerator_from_item_in_section (GLOMenu *menu, - gint section, - gint position) -{ - g_return_val_if_fail (G_IS_LO_MENU (menu), nullptr); - - GVariant *accel_value = g_lo_menu_get_attribute_value_from_item_in_section (menu, - section, - position, - G_LO_MENU_ATTRIBUTE_ACCELERATOR, - G_VARIANT_TYPE_STRING); - - gchar *accel = nullptr; - - if (accel_value != nullptr) - { - accel = g_variant_dup_string (accel_value, nullptr); - g_variant_unref (accel_value); - } - - return accel; -} - -void -g_lo_menu_set_command_to_item_in_section (GLOMenu *menu, - gint section, - gint position, - const gchar *command) -{ - g_return_if_fail (G_IS_LO_MENU (menu)); - - GLOMenu *model = g_lo_menu_get_section (menu, section); - - g_return_if_fail (model != nullptr); - - GVariant *value; - - if (command != nullptr) - value = g_variant_new_string (command); - else - value = nullptr; - - g_lo_menu_set_attribute_value (model, position, G_LO_MENU_ATTRIBUTE_COMMAND, value); - - // Notify the update. - g_menu_model_items_changed (G_MENU_MODEL (model), position, 1, 1); - - g_object_unref (model); -} - -gchar * -g_lo_menu_get_command_from_item_in_section (GLOMenu *menu, - gint section, - gint position) -{ - g_return_val_if_fail (G_IS_LO_MENU (menu), nullptr); - - GVariant *command_value = g_lo_menu_get_attribute_value_from_item_in_section (menu, - section, - position, - G_LO_MENU_ATTRIBUTE_COMMAND, - G_VARIANT_TYPE_STRING); - - gchar *command = nullptr; - - if (command_value != nullptr) - { - command = g_variant_dup_string (command_value, nullptr); - g_variant_unref (command_value); - } - - return command; -} - -static void -g_lo_menu_set_link (GLOMenu *menu, - gint position, - const gchar *link, - GMenuModel *model) -{ - g_return_if_fail (G_IS_LO_MENU (menu)); - g_return_if_fail (link != nullptr); - g_return_if_fail (valid_attribute_name (link)); - - if (position < 0 || position >= static_cast<gint>(menu->items->len)) - position = menu->items->len - 1; - - struct item menu_item = g_array_index (menu->items, struct item, position); - - if (model != nullptr) - g_hash_table_insert (menu_item.links, g_strdup (link), g_object_ref (model)); - else - g_hash_table_remove (menu_item.links, link); -} - -void -g_lo_menu_insert_section (GLOMenu *menu, - gint position, - const gchar *label, - GMenuModel *section) -{ - g_return_if_fail (G_IS_LO_MENU (menu)); - - if (position < 0 || position > static_cast<gint>(menu->items->len)) - position = menu->items->len; - - struct item menu_item; - - g_lo_menu_struct_item_init(&menu_item); - - g_array_insert_val (menu->items, position, menu_item); - - g_lo_menu_set_label (menu, position, label); - g_lo_menu_set_link (menu, position, G_MENU_LINK_SECTION, section); - - g_menu_model_items_changed (G_MENU_MODEL (menu), position, 0, 1); -} - -void -g_lo_menu_new_section (GLOMenu *menu, - gint position, - const gchar *label) -{ - GMenuModel *section = G_MENU_MODEL (g_lo_menu_new()); - - g_lo_menu_insert_section (menu, position, label, section); - - g_object_unref (section); -} - -GLOMenu * -g_lo_menu_get_section (GLOMenu *menu, - gint section) -{ - g_return_val_if_fail (G_IS_LO_MENU (menu), nullptr); - - return G_LO_MENU (G_MENU_MODEL_CLASS (g_lo_menu_parent_class) - ->get_item_link (G_MENU_MODEL (menu), section, G_MENU_LINK_SECTION)); -} - -void -g_lo_menu_new_submenu_in_item_in_section (GLOMenu *menu, - gint section, - gint position) -{ - g_return_if_fail (G_IS_LO_MENU (menu)); - g_return_if_fail (0 <= section && section < static_cast<gint>(menu->items->len)); - - GLOMenu* model = g_lo_menu_get_section (menu, section); - - g_return_if_fail (model != nullptr); - - if (0 <= position && position < static_cast<gint>(model->items->len)) { - GMenuModel* submenu = G_MENU_MODEL (g_lo_menu_new()); - - g_lo_menu_set_link (model, position, G_MENU_LINK_SUBMENU, submenu); - - g_object_unref (submenu); - - g_menu_model_items_changed (G_MENU_MODEL (model), position, 1, 1); - - g_object_unref (model); - } -} - -GLOMenu * -g_lo_menu_get_submenu_from_item_in_section (GLOMenu *menu, - gint section, - gint position) -{ - g_return_val_if_fail (G_IS_LO_MENU (menu), nullptr); - g_return_val_if_fail (0 <= section && section < static_cast<gint>(menu->items->len), nullptr); - - GLOMenu *model = g_lo_menu_get_section (menu, section); - - g_return_val_if_fail (model != nullptr, nullptr); - - GLOMenu *submenu = nullptr; - - if (0 <= position && position < static_cast<gint>(model->items->len)) - submenu = G_LO_MENU (G_MENU_MODEL_CLASS (g_lo_menu_parent_class) - ->get_item_link (G_MENU_MODEL (model), position, G_MENU_LINK_SUBMENU)); - //submenu = g_menu_model_get_item_link (G_MENU_MODEL (model), position, G_MENU_LINK_SUBMENU); - - g_object_unref (model); - - return submenu; -} - -void -g_lo_menu_set_submenu_action_to_item_in_section (GLOMenu *menu, - gint section, - gint position, - const gchar *action) -{ - g_return_if_fail (G_IS_LO_MENU (menu)); - - GMenuModel *model = G_MENU_MODEL (g_lo_menu_get_section (menu, section)); - - g_return_if_fail (model != nullptr); - - GVariant *value; - - if (action != nullptr) - value = g_variant_new_string (action); - else - value = nullptr; - - g_lo_menu_set_attribute_value (G_LO_MENU (model), position, G_LO_MENU_ATTRIBUTE_SUBMENU_ACTION, value); - - // Notify the update. - g_menu_model_items_changed (model, position, 1, 1); - - g_object_unref (model); -} - -static void -g_lo_menu_clear_item (struct item *menu_item) -{ - if (menu_item->attributes != nullptr) - g_hash_table_unref (menu_item->attributes); - if (menu_item->links != nullptr) - g_hash_table_unref (menu_item->links); -} - -void -g_lo_menu_remove (GLOMenu *menu, - gint position) -{ - g_return_if_fail (G_IS_LO_MENU (menu)); - g_return_if_fail (0 <= position && position < static_cast<gint>(menu->items->len)); - - g_lo_menu_clear_item (&g_array_index (menu->items, struct item, position)); - g_array_remove_index (menu->items, position); - g_menu_model_items_changed (G_MENU_MODEL (menu), position, 1, 0); -} - -void -g_lo_menu_remove_from_section (GLOMenu *menu, - gint section, - gint position) -{ - g_return_if_fail (G_IS_LO_MENU (menu)); - g_return_if_fail (0 <= section && section < static_cast<gint>(menu->items->len)); - - GLOMenu *model = g_lo_menu_get_section (menu, section); - - g_return_if_fail (model != nullptr); - - g_lo_menu_remove (model, position); - - g_object_unref (model); -} - -static void -g_lo_menu_finalize (GObject *object) -{ - GLOMenu *menu = G_LO_MENU (object); - struct item *items; - gint n_items; - gint i; - - n_items = menu->items->len; - items = reinterpret_cast<struct item *>(g_array_free (menu->items, FALSE)); - for (i = 0; i < n_items; i++) - g_lo_menu_clear_item (&items[i]); - g_free (items); - - G_OBJECT_CLASS (g_lo_menu_parent_class) - ->finalize (object); -} - -static void -g_lo_menu_init (GLOMenu *menu) -{ - menu->items = g_array_new (FALSE, FALSE, sizeof (struct item)); -} - -static void -g_lo_menu_class_init (GLOMenuClass *klass) -{ - GMenuModelClass *model_class = G_MENU_MODEL_CLASS (klass); - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = g_lo_menu_finalize; - - model_class->is_mutable = g_lo_menu_is_mutable; - model_class->get_n_items = g_lo_menu_get_n_items; - model_class->get_item_attributes = g_lo_menu_get_item_attributes; - model_class->get_item_links = g_lo_menu_get_item_links; -} - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/gtkdata.cxx b/vcl/unx/gtk/gtkdata.cxx deleted file mode 100644 index ca7a567f7402..000000000000 --- a/vcl/unx/gtk/gtkdata.cxx +++ /dev/null @@ -1,890 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include <unistd.h> -#include <fcntl.h> - -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <limits.h> -#include <errno.h> -#include <poll.h> -#if defined(FREEBSD) || defined(NETBSD) -#include <sys/types.h> -#include <sys/time.h> -#endif -#include <unx/gtk/gtkdata.hxx> -#include <unx/gtk/gtkinst.hxx> -#include <unx/gtk/gtkframe.hxx> -#include <unx/gtk/gtksalmenu.hxx> -#include <unx/salobj.h> -#include <unx/geninst.h> -#include <osl/thread.h> -#include <osl/process.h> -#include <sal/log.hxx> - -#include <unx/i18n_im.hxx> -#include <unx/i18n_xkb.hxx> -#include <unx/wmadaptor.hxx> - -#include <unx/x11_cursors/salcursors.h> - -#include <vcl/svapp.hxx> -#include <chrono> - -using namespace vcl_sal; - -/*************************************************************** - * class GtkSalDisplay * - ***************************************************************/ -extern "C" { -static GdkFilterReturn call_filterGdkEvent( GdkXEvent* sys_event, - GdkEvent* /*event*/, - gpointer data ) -{ - GtkSalDisplay *pDisplay = static_cast<GtkSalDisplay *>(data); - return pDisplay->filterGdkEvent( sys_event ); -} -} - -GtkSalDisplay::GtkSalDisplay( GdkDisplay* pDisplay ) : - SalDisplay( gdk_x11_display_get_xdisplay( pDisplay ) ), - m_pSys( GtkSalSystem::GetSingleton() ), - m_pGdkDisplay( pDisplay ), - m_bStartupCompleted( false ) -{ - for(GdkCursor* & rpCsr : m_aCursors) - rpCsr = nullptr; - m_bUseRandRWrapper = false; // use gdk signal instead - Init (); - - // FIXME: unify this with SalInst's filter too ? - gdk_window_add_filter( nullptr, call_filterGdkEvent, this ); - - if ( getenv( "SAL_IGNOREXERRORS" ) ) - GetGenericUnixSalData()->ErrorTrapPush(); // and leak the trap - - m_bX11Display = true; - - gtk_widget_set_default_direction(AllSettings::GetLayoutRTL() ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR); -} - -GtkSalDisplay::~GtkSalDisplay() -{ - gdk_window_remove_filter( nullptr, call_filterGdkEvent, this ); - - if( !m_bStartupCompleted ) - gdk_notify_startup_complete(); - - doDestruct(); - pDisp_ = nullptr; - - for(GdkCursor* & rpCsr : m_aCursors) - if( rpCsr ) - gdk_cursor_unref( rpCsr ); -} - -extern "C" { - -static void signalScreenSizeChanged( GdkScreen* pScreen, gpointer data ) -{ - GtkSalDisplay* pDisp = static_cast<GtkSalDisplay*>(data); - pDisp->screenSizeChanged( pScreen ); -} - -static void signalMonitorsChanged( GdkScreen* pScreen, gpointer data ) -{ - GtkSalDisplay* pDisp = static_cast<GtkSalDisplay*>(data); - pDisp->monitorsChanged( pScreen ); -} - -} - -GdkFilterReturn GtkSalDisplay::filterGdkEvent( GdkXEvent* sys_event ) -{ - GdkFilterReturn aFilterReturn = GDK_FILTER_CONTINUE; - XEvent *pEvent = static_cast<XEvent *>(sys_event); - - // dispatch all XEvents to event callback - if( GetSalData()->m_pInstance-> - CallEventCallback( pEvent, sizeof( XEvent ) ) ) - aFilterReturn = GDK_FILTER_REMOVE; - - if (GetDisplay() == pEvent->xany.display ) - { - // #i53471# gtk has no callback mechanism that lets us be notified - // when settings (as in XSETTING and opposed to styles) are changed. - // so we need to listen for corresponding property notifications here - // these should be rare enough so that we can assume that the settings - // actually change when a corresponding PropertyNotify occurs - SalFrame *pAnyFrame = anyFrame(); - if( pAnyFrame && pEvent->type == PropertyNotify && - pEvent->xproperty.atom == getWMAdaptor()->getAtom( WMAdaptor::XSETTINGS ) ) - { - PostEvent( pAnyFrame, nullptr, SalEvent::SettingsChanged ); - } - // let's see if one of our frames wants to swallow these events - // get the frame - for (auto pSalFrame : m_aFrames ) - { - GtkSalFrame* pFrame = static_cast<GtkSalFrame*>( pSalFrame ); - if( pFrame->GetSystemData()->aWindow == pEvent->xany.window || - ( pFrame->getForeignParent() && pFrame->getForeignParentWindow() == pEvent->xany.window ) || - ( pFrame->getForeignTopLevel() && pFrame->getForeignTopLevelWindow() == pEvent->xany.window ) - ) - { - if( ! pFrame->Dispatch( pEvent ) ) - aFilterReturn = GDK_FILTER_REMOVE; - break; - } - } - X11SalObject::Dispatch( pEvent ); - } - - return aFilterReturn; -} - -void GtkSalDisplay::screenSizeChanged( GdkScreen const * pScreen ) -{ - m_pSys->countScreenMonitors(); - if (pScreen) - emitDisplayChanged(); -} - -void GtkSalDisplay::monitorsChanged( GdkScreen const * pScreen ) -{ - m_pSys->countScreenMonitors(); - if (pScreen) - emitDisplayChanged(); -} - -SalDisplay::ScreenData * -GtkSalDisplay::initScreen( SalX11Screen nXScreen ) const -{ - // choose visual for screen - ScreenData *pSD; - if (!(pSD = SalDisplay::initScreen( nXScreen ))) - return nullptr; - - // now set a gdk default colormap matching the chosen visual to the screen - GdkScreen* pScreen = gdk_display_get_screen( m_pGdkDisplay, nXScreen.getXScreen() ); -// should really use this: -// GdkVisual* pVis = gdk_x11_screen_lookup_visual_get( screen, pSD->m_aVisual.visualid ); -// and not this: - GdkVisual* pVis = gdkx_visual_get( pSD->m_aVisual.visualid ); - if( pVis ) - { - GdkColormap* pDefCol = gdk_screen_get_default_colormap( pScreen ); - GdkVisual* pDefVis = gdk_colormap_get_visual( pDefCol ); - if( pDefVis != pVis ) - { - pDefCol = gdk_x11_colormap_foreign_new( pVis, pSD->m_aColormap.GetXColormap() ); - gdk_screen_set_default_colormap( pScreen, pDefCol ); - SAL_INFO( "vcl.gtk", "set new gdk color map for screen " << nXScreen.getXScreen() ); - } - } - else - SAL_INFO( "vcl.gtk", "not GdkVisual for visual id " << pSD->m_aVisual.visualid ); - - return pSD; -} - -bool GtkSalDisplay::Dispatch( XEvent* pEvent ) -{ - if( GetDisplay() == pEvent->xany.display ) - { - // let's see if one of our frames wants to swallow these events - // get the child frame - for (auto pSalFrame : m_aFrames ) - { - if (pSalFrame->GetSystemData()->aWindow == pEvent->xany.window) - return static_cast<GtkSalFrame*>( pSalFrame )->Dispatch( pEvent ); - } - } - - return false; -} - -GdkCursor* GtkSalDisplay::getFromXBM( const unsigned char *pBitmap, - const unsigned char *pMask, - int nWidth, int nHeight, - int nXHot, int nYHot ) -{ - GdkScreen *pScreen = gdk_display_get_default_screen( m_pGdkDisplay ); - GdkDrawable *pDrawable = GDK_DRAWABLE( gdk_screen_get_root_window (pScreen) ); - GdkBitmap *pBitmapPix = gdk_bitmap_create_from_data - ( pDrawable, reinterpret_cast<const char*>(pBitmap), nWidth, nHeight ); - GdkBitmap *pMaskPix = gdk_bitmap_create_from_data - ( pDrawable, reinterpret_cast<const char*>(pMask), nWidth, nHeight ); - GdkColormap *pColormap = gdk_drawable_get_colormap( pDrawable ); - - GdkColor aWhite = { 0, 0xffff, 0xffff, 0xffff }; - GdkColor aBlack = { 0, 0, 0, 0 }; - - gdk_colormap_alloc_color( pColormap, &aBlack, FALSE, TRUE); - gdk_colormap_alloc_color( pColormap, &aWhite, FALSE, TRUE); - - return gdk_cursor_new_from_pixmap - ( pBitmapPix, pMaskPix, - &aBlack, &aWhite, nXHot, nYHot); -} - -static unsigned char nullmask_bits[] = { 0x00, 0x00, 0x00, 0x00 }; -static unsigned char nullcurs_bits[] = { 0x00, 0x00, 0x00, 0x00 }; - -#define MAKE_CURSOR( vcl_name, name ) \ - case vcl_name: \ - pCursor = getFromXBM( name##curs##_bits, name##mask##_bits, \ - name##curs_width, name##curs_height, \ - name##curs_x_hot, name##curs_y_hot ); \ - break -#define MAP_BUILTIN( vcl_name, gdk_name ) \ - case vcl_name: \ - pCursor = gdk_cursor_new_for_display( m_pGdkDisplay, gdk_name ); \ - break - -GdkCursor *GtkSalDisplay::getCursor( PointerStyle ePointerStyle ) -{ - if ( !m_aCursors[ ePointerStyle ] ) - { - GdkCursor *pCursor = nullptr; - - switch( ePointerStyle ) - { - MAP_BUILTIN( PointerStyle::Arrow, GDK_LEFT_PTR ); - MAP_BUILTIN( PointerStyle::Text, GDK_XTERM ); - MAP_BUILTIN( PointerStyle::Help, GDK_QUESTION_ARROW ); - MAP_BUILTIN( PointerStyle::Cross, GDK_CROSSHAIR ); - MAP_BUILTIN( PointerStyle::Wait, GDK_WATCH ); - - MAP_BUILTIN( PointerStyle::NSize, GDK_SB_V_DOUBLE_ARROW ); - MAP_BUILTIN( PointerStyle::SSize, GDK_SB_V_DOUBLE_ARROW ); - MAP_BUILTIN( PointerStyle::WSize, GDK_SB_H_DOUBLE_ARROW ); - MAP_BUILTIN( PointerStyle::ESize, GDK_SB_H_DOUBLE_ARROW ); - - MAP_BUILTIN( PointerStyle::NWSize, GDK_TOP_LEFT_CORNER ); - MAP_BUILTIN( PointerStyle::NESize, GDK_TOP_RIGHT_CORNER ); - MAP_BUILTIN( PointerStyle::SWSize, GDK_BOTTOM_LEFT_CORNER ); - MAP_BUILTIN( PointerStyle::SESize, GDK_BOTTOM_RIGHT_CORNER ); - - MAP_BUILTIN( PointerStyle::WindowNSize, GDK_TOP_SIDE ); - MAP_BUILTIN( PointerStyle::WindowSSize, GDK_BOTTOM_SIDE ); - MAP_BUILTIN( PointerStyle::WindowWSize, GDK_LEFT_SIDE ); - MAP_BUILTIN( PointerStyle::WindowESize, GDK_RIGHT_SIDE ); - - MAP_BUILTIN( PointerStyle::WindowNWSize, GDK_TOP_LEFT_CORNER ); - MAP_BUILTIN( PointerStyle::WindowNESize, GDK_TOP_RIGHT_CORNER ); - MAP_BUILTIN( PointerStyle::WindowSWSize, GDK_BOTTOM_LEFT_CORNER ); - MAP_BUILTIN( PointerStyle::WindowSESize, GDK_BOTTOM_RIGHT_CORNER ); - - MAP_BUILTIN( PointerStyle::HSizeBar, GDK_SB_H_DOUBLE_ARROW ); - MAP_BUILTIN( PointerStyle::VSizeBar, GDK_SB_V_DOUBLE_ARROW ); - - MAP_BUILTIN( PointerStyle::RefHand, GDK_HAND2 ); - MAP_BUILTIN( PointerStyle::Hand, GDK_HAND2 ); - MAP_BUILTIN( PointerStyle::Pen, GDK_PENCIL ); - - MAP_BUILTIN( PointerStyle::HSplit, GDK_SB_H_DOUBLE_ARROW ); - MAP_BUILTIN( PointerStyle::VSplit, GDK_SB_V_DOUBLE_ARROW ); - - MAP_BUILTIN( PointerStyle::Move, GDK_FLEUR ); - - MAKE_CURSOR( PointerStyle::Null, null ); - MAKE_CURSOR( PointerStyle::Magnify, magnify_ ); - MAKE_CURSOR( PointerStyle::Fill, fill_ ); - MAKE_CURSOR( PointerStyle::MoveData, movedata_ ); - MAKE_CURSOR( PointerStyle::CopyData, copydata_ ); - MAKE_CURSOR( PointerStyle::MoveFile, movefile_ ); - MAKE_CURSOR( PointerStyle::CopyFile, copyfile_ ); - MAKE_CURSOR( PointerStyle::MoveFiles, movefiles_ ); - MAKE_CURSOR( PointerStyle::CopyFiles, copyfiles_ ); - MAKE_CURSOR( PointerStyle::NotAllowed, nodrop_ ); - MAKE_CURSOR( PointerStyle::Rotate, rotate_ ); - MAKE_CURSOR( PointerStyle::HShear, hshear_ ); - MAKE_CURSOR( PointerStyle::VShear, vshear_ ); - MAKE_CURSOR( PointerStyle::DrawLine, drawline_ ); - MAKE_CURSOR( PointerStyle::DrawRect, drawrect_ ); - MAKE_CURSOR( PointerStyle::DrawPolygon, drawpolygon_ ); - MAKE_CURSOR( PointerStyle::DrawBezier, drawbezier_ ); - MAKE_CURSOR( PointerStyle::DrawArc, drawarc_ ); - MAKE_CURSOR( PointerStyle::DrawPie, drawpie_ ); - MAKE_CURSOR( PointerStyle::DrawCircleCut, drawcirclecut_ ); - MAKE_CURSOR( PointerStyle::DrawEllipse, drawellipse_ ); - MAKE_CURSOR( PointerStyle::DrawConnect, drawconnect_ ); - MAKE_CURSOR( PointerStyle::DrawText, drawtext_ ); - MAKE_CURSOR( PointerStyle::Mirror, mirror_ ); - MAKE_CURSOR( PointerStyle::Crook, crook_ ); - MAKE_CURSOR( PointerStyle::Crop, crop_ ); - MAKE_CURSOR( PointerStyle::MovePoint, movepoint_ ); - MAKE_CURSOR( PointerStyle::MoveBezierWeight, movebezierweight_ ); - MAKE_CURSOR( PointerStyle::DrawFreehand, drawfreehand_ ); - MAKE_CURSOR( PointerStyle::DrawCaption, drawcaption_ ); - MAKE_CURSOR( PointerStyle::LinkData, linkdata_ ); - MAKE_CURSOR( PointerStyle::MoveDataLink, movedlnk_ ); - MAKE_CURSOR( PointerStyle::CopyDataLink, copydlnk_ ); - MAKE_CURSOR( PointerStyle::LinkFile, linkfile_ ); - MAKE_CURSOR( PointerStyle::MoveFileLink, moveflnk_ ); - MAKE_CURSOR( PointerStyle::CopyFileLink, copyflnk_ ); - MAKE_CURSOR( PointerStyle::Chart, chart_ ); - MAKE_CURSOR( PointerStyle::Detective, detective_ ); - MAKE_CURSOR( PointerStyle::PivotCol, pivotcol_ ); - MAKE_CURSOR( PointerStyle::PivotRow, pivotrow_ ); - MAKE_CURSOR( PointerStyle::PivotField, pivotfld_ ); - MAKE_CURSOR( PointerStyle::PivotDelete, pivotdel_ ); - MAKE_CURSOR( PointerStyle::Chain, chain_ ); - MAKE_CURSOR( PointerStyle::ChainNotAllowed, chainnot_ ); - MAKE_CURSOR( PointerStyle::AutoScrollN, asn_ ); - MAKE_CURSOR( PointerStyle::AutoScrollS, ass_ ); - MAKE_CURSOR( PointerStyle::AutoScrollW, asw_ ); - MAKE_CURSOR( PointerStyle::AutoScrollE, ase_ ); - MAKE_CURSOR( PointerStyle::AutoScrollNW, asnw_ ); - MAKE_CURSOR( PointerStyle::AutoScrollNE, asne_ ); - MAKE_CURSOR( PointerStyle::AutoScrollSW, assw_ ); - MAKE_CURSOR( PointerStyle::AutoScrollSE, asse_ ); - MAKE_CURSOR( PointerStyle::AutoScrollNS, asns_ ); - MAKE_CURSOR( PointerStyle::AutoScrollWE, aswe_ ); - MAKE_CURSOR( PointerStyle::AutoScrollNSWE, asnswe_ ); - MAKE_CURSOR( PointerStyle::TextVertical, vertcurs_ ); - - // #i32329# - MAKE_CURSOR( PointerStyle::TabSelectS, tblsels_ ); - MAKE_CURSOR( PointerStyle::TabSelectE, tblsele_ ); - MAKE_CURSOR( PointerStyle::TabSelectSE, tblselse_ ); - MAKE_CURSOR( PointerStyle::TabSelectW, tblselw_ ); - MAKE_CURSOR( PointerStyle::TabSelectSW, tblselsw_ ); - - MAKE_CURSOR( PointerStyle::HideWhitespace, hidewhitespace_ ); - MAKE_CURSOR( PointerStyle::ShowWhitespace, showwhitespace_ ); - - default: - SAL_WARN( "vcl.gtk", "pointer " << static_cast<int>(ePointerStyle) << "not implemented" ); - break; - } - if( !pCursor ) - pCursor = gdk_cursor_new_for_display( m_pGdkDisplay, GDK_LEFT_PTR ); - - m_aCursors[ ePointerStyle ] = pCursor; - } - - return m_aCursors[ ePointerStyle ]; -} - -int GtkSalDisplay::CaptureMouse( SalFrame* pSFrame ) -{ - GtkSalFrame* pFrame = static_cast<GtkSalFrame*>(pSFrame); - - if( !pFrame ) - { - if( m_pCapture ) - static_cast<GtkSalFrame*>(m_pCapture)->grabPointer( FALSE ); - m_pCapture = nullptr; - return 0; - } - - if( m_pCapture ) - { - if( pFrame == m_pCapture ) - return 1; - static_cast<GtkSalFrame*>(m_pCapture)->grabPointer( FALSE ); - } - - m_pCapture = pFrame; - pFrame->grabPointer( TRUE ); - return 1; -} - -/********************************************************************** - * class GtkSalData * - **********************************************************************/ - -GtkSalData::GtkSalData( SalInstance *pInstance ) - : GenericUnixSalData( SAL_DATA_GTK, pInstance ) - , m_aDispatchMutex() - , m_aDispatchCondition() - , m_pDocumentFocusListener(nullptr) -{ - m_pUserEvent = nullptr; -} - -static XIOErrorHandler aOrigXIOErrorHandler = nullptr; - -extern "C" { - -static int XIOErrorHdl(Display *) -{ - fprintf(stderr, "X IO Error\n"); - _exit(1); - // avoid crashes in unrelated threads that still run while atexit - // handlers are in progress -} - -} - -GtkSalData::~GtkSalData() -{ - Yield( true, true ); - g_warning ("TESTME: We used to have a stop-timer here, but the central code should do this"); - - // sanity check: at this point nobody should be yielding, but wake them - // up anyway before the condition they're waiting on gets destroyed. - m_aDispatchCondition.set(); - - osl::MutexGuard g( m_aDispatchMutex ); - if (m_pUserEvent) - { - g_source_destroy (m_pUserEvent); - g_source_unref (m_pUserEvent); - m_pUserEvent = nullptr; - } - XSetIOErrorHandler(aOrigXIOErrorHandler); -} - -void GtkSalData::Dispose() -{ - deInitNWF(); -} - -/// Allows events to be processed, returns true if we processed an event. -bool GtkSalData::Yield( bool bWait, bool bHandleAllCurrentEvents ) -{ - /* #i33212# only enter g_main_context_iteration in one thread at any one - * time, else one of them potentially will never end as long as there is - * another thread in there. Having only one yielding thread actually dispatch - * fits the vcl event model (see e.g. the generic plugin). - */ - bool bDispatchThread = false; - bool bWasEvent = false; - { - // release YieldMutex (and re-acquire at block end) - SolarMutexReleaser aReleaser; - if( m_aDispatchMutex.tryToAcquire() ) - bDispatchThread = true; - else if( ! bWait ) - { - return false; // someone else is waiting already, return - } - - if( bDispatchThread ) - { - int nMaxEvents = bHandleAllCurrentEvents ? 100 : 1; - gboolean wasOneEvent = TRUE; - while( nMaxEvents-- && wasOneEvent ) - { - wasOneEvent = g_main_context_iteration( nullptr, bWait && !bWasEvent ); - if( wasOneEvent ) - bWasEvent = true; - } - } - else if( bWait ) - { - /* #i41693# in case the dispatch thread hangs in join - * for this thread the condition will never be set - * workaround: timeout of 1 second an emergency exit - */ - // we are the dispatch thread - m_aDispatchCondition.reset(); - m_aDispatchCondition.wait( std::chrono::seconds(1) ); - } - } - - if( bDispatchThread ) - { - m_aDispatchMutex.release(); - if( bWasEvent ) - m_aDispatchCondition.set(); // trigger non dispatch thread yields - } - - return bWasEvent; -} - -void GtkSalData::Init() -{ - int i; - SAL_INFO( "vcl.gtk", "GtkMainloop::Init()" ); - XrmInitialize(); - - gtk_set_locale(); - - /* - * open connection to X11 Display - * try in this order: - * o -display command line parameter, - * o $DISPLAY environment variable - * o default display - */ - - GdkDisplay *pGdkDisp = nullptr; - - // is there a -display command line parameter? - rtl_TextEncoding aEnc = osl_getThreadTextEncoding(); - int nParams = osl_getCommandArgCount(); - OString aDisplay; - OUString aParam, aBin; - char** pCmdLineAry = new char*[ nParams+1 ]; - osl_getExecutableFile( &aParam.pData ); - osl_getSystemPathFromFileURL( aParam.pData, &aBin.pData ); - pCmdLineAry[0] = g_strdup( OUStringToOString( aBin, aEnc ).getStr() ); - for (i=0; i<nParams; i++) - { - osl_getCommandArg(i, &aParam.pData ); - OString aBParam( OUStringToOString( aParam, aEnc ) ); - - if( aParam == "-display" || aParam == "--display" ) - { - pCmdLineAry[i+1] = g_strdup( "--display" ); - osl_getCommandArg(i+1, &aParam.pData ); - aDisplay = OUStringToOString( aParam, aEnc ); - } - else - pCmdLineAry[i+1] = g_strdup( aBParam.getStr() ); - } - // add executable - nParams++; - - g_set_application_name(SalGenericSystem::getFrameClassName()); - - // Set consistent name of the root accessible - OUString aAppName = Application::GetAppName(); - if( !aAppName.isEmpty() ) - { - OString aPrgName = OUStringToOString(aAppName, aEnc); - g_set_prgname(aPrgName.getStr()); - } - - // init gtk/gdk - gtk_init_check( &nParams, &pCmdLineAry ); - gdk_error_trap_push(); - - for (i = 0; i < nParams; i++ ) - g_free( pCmdLineAry[i] ); - delete [] pCmdLineAry; - -#if OSL_DEBUG_LEVEL > 1 - if (g_getenv ("SAL_DEBUG_UPDATES")) - gdk_window_set_debug_updates (TRUE); -#endif - - pGdkDisp = gdk_display_get_default(); - if ( !pGdkDisp ) - { - OUString aProgramFileURL; - osl_getExecutableFile( &aProgramFileURL.pData ); - OUString aProgramSystemPath; - osl_getSystemPathFromFileURL (aProgramFileURL.pData, &aProgramSystemPath.pData); - OString aProgramName = OUStringToOString( - aProgramSystemPath, - osl_getThreadTextEncoding() ); - fprintf( stderr, "%s X11 error: Can't open display: %s\n", - aProgramName.getStr(), aDisplay.getStr()); - fprintf( stderr, " Set DISPLAY environment variable, use -display option\n"); - fprintf( stderr, " or check permissions of your X-Server\n"); - fprintf( stderr, " (See \"man X\" resp. \"man xhost\" for details)\n"); - fflush( stderr ); - exit(0); - } - - aOrigXIOErrorHandler = XSetIOErrorHandler(XIOErrorHdl); - - /* - * if a -display switch was used, we need - * to set the environment accordingly since - * the clipboard build another connection - * to the xserver using $DISPLAY - */ - OUString envVar("DISPLAY"); - const gchar *name = gdk_display_get_name( pGdkDisp ); - OUString envValue(name, strlen(name), aEnc); - osl_setEnvironment(envVar.pData, envValue.pData); - - GtkSalDisplay *pDisplay = new GtkSalDisplay( pGdkDisp ); - SetDisplay( pDisplay ); - - Display *pDisp = gdk_x11_display_get_xdisplay( pGdkDisp ); - - gdk_error_trap_push(); - SalI18N_KeyboardExtension *pKbdExtension = new SalI18N_KeyboardExtension( pDisp ); - bool bErrorOccured = gdk_error_trap_pop() != 0; - gdk_error_trap_push(); - pKbdExtension->UseExtension( bErrorOccured ); - gdk_error_trap_pop(); - GetGtkDisplay()->SetKbdExtension( pKbdExtension ); - - // add signal handler to notify screen size changes - int nScreens = gdk_display_get_n_screens( pGdkDisp ); - for( int n = 0; n < nScreens; n++ ) - { - GdkScreen *pScreen = gdk_display_get_screen( pGdkDisp, n ); - if( pScreen ) - { - pDisplay->screenSizeChanged( pScreen ); - pDisplay->monitorsChanged( pScreen ); - g_signal_connect( G_OBJECT(pScreen), "size-changed", - G_CALLBACK(signalScreenSizeChanged), pDisplay ); - g_signal_connect( G_OBJECT(pScreen), "monitors-changed", - G_CALLBACK(signalMonitorsChanged), GetGtkDisplay() ); - } - } -} - -void GtkSalData::ErrorTrapPush() -{ - gdk_error_trap_push (); -} - -bool GtkSalData::ErrorTrapPop( bool ) -{ - return gdk_error_trap_pop () != 0; -} - -#if !GLIB_CHECK_VERSION(2,32,0) -#define G_SOURCE_REMOVE FALSE -#endif - -extern "C" { - - struct SalGtkTimeoutSource { - GSource aParent; - GTimeVal aFireTime; - GtkSalTimer *pInstance; - }; - - static void sal_gtk_timeout_defer( SalGtkTimeoutSource *pTSource ) - { - g_get_current_time( &pTSource->aFireTime ); - g_time_val_add( &pTSource->aFireTime, pTSource->pInstance->m_nTimeoutMS * 1000 ); - } - - static gboolean sal_gtk_timeout_expired( SalGtkTimeoutSource *pTSource, - gint *nTimeoutMS, GTimeVal const *pTimeNow ) - { - glong nDeltaSec = pTSource->aFireTime.tv_sec - pTimeNow->tv_sec; - glong nDeltaUSec = pTSource->aFireTime.tv_usec - pTimeNow->tv_usec; - if( nDeltaSec < 0 || ( nDeltaSec == 0 && nDeltaUSec < 0) ) - { - *nTimeoutMS = 0; - return TRUE; - } - if( nDeltaUSec < 0 ) - { - nDeltaUSec += 1000000; - nDeltaSec -= 1; - } - // if the clock changes backwards we need to cope ... - if( static_cast<unsigned long>(nDeltaSec) > 1 + ( pTSource->pInstance->m_nTimeoutMS / 1000 ) ) - { - sal_gtk_timeout_defer( pTSource ); - return TRUE; - } - - *nTimeoutMS = MIN( G_MAXINT, ( nDeltaSec * 1000 + (nDeltaUSec + 999) / 1000 ) ); - - return *nTimeoutMS == 0; - } - - static gboolean sal_gtk_timeout_prepare( GSource *pSource, gint *nTimeoutMS ) - { - SalGtkTimeoutSource *pTSource = reinterpret_cast<SalGtkTimeoutSource *>(pSource); - - GTimeVal aTimeNow; - g_get_current_time( &aTimeNow ); - - return sal_gtk_timeout_expired( pTSource, nTimeoutMS, &aTimeNow ); - } - - static gboolean sal_gtk_timeout_check( GSource *pSource ) - { - SalGtkTimeoutSource *pTSource = reinterpret_cast<SalGtkTimeoutSource *>(pSource); - - GTimeVal aTimeNow; - g_get_current_time( &aTimeNow ); - - return ( pTSource->aFireTime.tv_sec < aTimeNow.tv_sec || - ( pTSource->aFireTime.tv_sec == aTimeNow.tv_sec && - pTSource->aFireTime.tv_usec < aTimeNow.tv_usec ) ); - } - - static gboolean sal_gtk_timeout_dispatch( GSource *pSource, GSourceFunc, gpointer ) - { - SalGtkTimeoutSource *pTSource = reinterpret_cast<SalGtkTimeoutSource *>(pSource); - - if( !pTSource->pInstance ) - return FALSE; - - SolarMutexGuard aGuard; - - sal_gtk_timeout_defer( pTSource ); - - ImplSVData* pSVData = ImplGetSVData(); - if( pSVData->maSchedCtx.mpSalTimer ) - pSVData->maSchedCtx.mpSalTimer->CallCallback(); - - return G_SOURCE_REMOVE; - } - - static GSourceFuncs sal_gtk_timeout_funcs = - { - sal_gtk_timeout_prepare, - sal_gtk_timeout_check, - sal_gtk_timeout_dispatch, - nullptr, nullptr, nullptr - }; -} - -static SalGtkTimeoutSource * -create_sal_gtk_timeout( GtkSalTimer *pTimer ) -{ - GSource *pSource = g_source_new( &sal_gtk_timeout_funcs, sizeof( SalGtkTimeoutSource ) ); - SalGtkTimeoutSource *pTSource = reinterpret_cast<SalGtkTimeoutSource *>(pSource); - pTSource->pInstance = pTimer; - - // #i36226# timers should be executed with lower priority - // than XEvents like in generic plugin - g_source_set_priority( pSource, G_PRIORITY_LOW ); - g_source_set_can_recurse( pSource, TRUE ); - g_source_set_callback( pSource, - /* unused dummy */ g_idle_remove_by_data, - nullptr, nullptr ); - g_source_attach( pSource, g_main_context_default() ); -#ifdef DBG_UTIL - g_source_set_name( pSource, "VCL timeout source" ); -#endif - - sal_gtk_timeout_defer( pTSource ); - - return pTSource; -} - -GtkSalTimer::GtkSalTimer() - : m_pTimeout(nullptr) - , m_nTimeoutMS(0) -{ -} - -GtkSalTimer::~GtkSalTimer() -{ - GtkInstance *pInstance = static_cast<GtkInstance *>(GetSalData()->m_pInstance); - pInstance->RemoveTimer(); - Stop(); -} - -bool GtkSalTimer::Expired() -{ - if( !m_pTimeout || g_source_is_destroyed( &m_pTimeout->aParent ) ) - return false; - - gint nDummy = 0; - GTimeVal aTimeNow; - g_get_current_time( &aTimeNow ); - return !!sal_gtk_timeout_expired( m_pTimeout, &nDummy, &aTimeNow); -} - -void GtkSalTimer::Start( sal_uInt64 nMS ) -{ - // glib is not 64bit safe in this regard. - assert( nMS <= G_MAXINT ); - if ( nMS > G_MAXINT ) - nMS = G_MAXINT; - m_nTimeoutMS = nMS; // for restarting - Stop(); // FIXME: ideally re-use an existing m_pTimeout - m_pTimeout = create_sal_gtk_timeout( this ); -} - -void GtkSalTimer::Stop() -{ - if( m_pTimeout ) - { - g_source_destroy( &m_pTimeout->aParent ); - g_source_unref( &m_pTimeout->aParent ); - m_pTimeout = nullptr; - } -} - -extern "C" { - static gboolean call_userEventFn( void *data ) - { - SolarMutexGuard aGuard; - const SalGenericDisplay *pDisplay = GetGenericUnixSalData()->GetDisplay(); - if ( pDisplay ) - { - GtkSalDisplay *pThisDisplay = static_cast<GtkSalData *>(data)->GetGtkDisplay(); - assert(static_cast<const SalGenericDisplay *>(pThisDisplay) == pDisplay); - pThisDisplay->DispatchInternalEvent(); - } - return TRUE; - } -} - -void GtkSalData::TriggerUserEventProcessing() -{ - if (m_pUserEvent) - g_main_context_wakeup (nullptr); // really needed ? - else // nothing pending anyway - { - m_pUserEvent = g_idle_source_new(); - // tdf#112890 some dialog don't appear under gtk2, use the same - // priority for user-events as gtk3 does since tdf#110737 - g_source_set_priority (m_pUserEvent, G_PRIORITY_HIGH_IDLE + 30); - g_source_set_can_recurse (m_pUserEvent, TRUE); - g_source_set_callback (m_pUserEvent, call_userEventFn, - static_cast<gpointer>(this), nullptr); - g_source_attach (m_pUserEvent, g_main_context_default ()); - } -} - -void GtkSalData::TriggerAllUserEventsProcessed() -{ - assert( m_pUserEvent ); - g_source_destroy( m_pUserEvent ); - g_source_unref( m_pUserEvent ); - m_pUserEvent = nullptr; -} - -void GtkSalDisplay::TriggerUserEventProcessing() -{ - GetGtkSalData()->TriggerUserEventProcessing(); -} - -void GtkSalDisplay::TriggerAllUserEventsProcessed() -{ - GetGtkSalData()->TriggerAllUserEventsProcessed(); -} - -GtkWidget* GtkSalDisplay::findGtkWidgetForNativeHandle(sal_uIntPtr hWindow) const -{ - for (auto pFrame : m_aFrames) - { - const SystemEnvData* pEnvData = pFrame->GetSystemData(); - if (pEnvData->aWindow == hWindow) - return GTK_WIDGET(pEnvData->pWidget); - } - return nullptr; -} - -void GtkSalDisplay::deregisterFrame( SalFrame* pFrame ) -{ - if( m_pCapture == pFrame ) - { - static_cast<GtkSalFrame*>(m_pCapture)->grabPointer( FALSE ); - m_pCapture = nullptr; - } - SalGenericDisplay::deregisterFrame( pFrame ); -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/gtkinst.cxx b/vcl/unx/gtk/gtkinst.cxx deleted file mode 100644 index 2a31b87e45cf..000000000000 --- a/vcl/unx/gtk/gtkinst.cxx +++ /dev/null @@ -1,478 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include <stack> -#include <string.h> -#include <osl/process.h> -#include <unx/gtk/gtkdata.hxx> -#include <unx/gtk/gtkinst.hxx> -#include <unx/salobj.h> -#include <unx/gtk/gtkgdi.hxx> -#include <unx/gtk/gtkframe.hxx> -#include <unx/gtk/gtkobject.hxx> -#include <unx/gtk/atkbridge.hxx> -#include <unx/gtk/gtkprn.hxx> -#include <unx/gtk/gtksalmenu.hxx> -#include <headless/svpvd.hxx> -#include <headless/svpbmp.hxx> -#include <vcl/inputtypes.hxx> -#include <unx/genpspgraphics.h> -#include <rtl/strbuf.hxx> -#include <sal/log.hxx> -#include <rtl/uri.hxx> - -#include <vcl/settings.hxx> - -#include <dlfcn.h> -#include <fcntl.h> -#include <unistd.h> - -#include <unx/gtk/gtkprintwrapper.hxx> - -extern "C" -{ - #define GET_YIELD_MUTEX() static_cast<GtkYieldMutex*>(GetSalData()->m_pInstance->GetYieldMutex()) - static void GdkThreadsEnter() - { - GtkYieldMutex *pYieldMutex = GET_YIELD_MUTEX(); - pYieldMutex->ThreadsEnter(); - } - static void GdkThreadsLeave() - { - GtkYieldMutex *pYieldMutex = GET_YIELD_MUTEX(); - pYieldMutex->ThreadsLeave(); - } - - VCLPLUG_GTK_PUBLIC SalInstance* create_SalInstance() - { - SAL_INFO( - "vcl.gtk", - "create vcl plugin instance with gtk version " << gtk_major_version - << " " << gtk_minor_version << " " << gtk_micro_version); - -#if !GTK_CHECK_VERSION(3,0,0) - if( gtk_major_version < 2 || // very unlikely sanity check - ( gtk_major_version == 2 && gtk_minor_version < 4 ) ) - { - g_warning("require a newer gtk than %d.%d for gdk_threads_set_lock_functions", static_cast<int>(gtk_major_version), gtk_minor_version); - return nullptr; - } -#else - if (gtk_major_version == 3 && gtk_minor_version < 18) - { - g_warning("require gtk >= 3.18 for theme expectations"); - return nullptr; - } -#endif - - // for gtk2 it is always built with X support, so this is always called - // for gtk3 it is normally built with X and Wayland support, if - // X is supported GDK_WINDOWING_X11 is defined and this is always - // called, regardless of if we're running under X or Wayland. - // We can't use (DLSYM_GDK_IS_X11_DISPLAY(pDisplay)) to only do it under - // X, because we need to do it earlier than we have a display -#if !GTK_CHECK_VERSION(3,0,0) || defined(GDK_WINDOWING_X11) - /* #i92121# workaround deadlocks in the X11 implementation - */ - static const char* pNoXInitThreads = getenv( "SAL_NO_XINITTHREADS" ); - /* #i90094# - from now on we know that an X connection will be - established, so protect X against itself - */ - if( ! ( pNoXInitThreads && *pNoXInitThreads ) ) - XInitThreads(); -#endif - - // init gdk thread protection - bool const sup = g_thread_supported(); - // extracted from the 'if' to avoid Clang -Wunreachable-code - if ( !sup ) - g_thread_init( nullptr ); - - gdk_threads_set_lock_functions (GdkThreadsEnter, GdkThreadsLeave); - SAL_INFO("vcl.gtk", "Hooked gdk threads locks"); - - auto pYieldMutex = std::make_unique<GtkYieldMutex>(); - - gdk_threads_init(); - - GtkInstance* pInstance = new GtkInstance( std::move(pYieldMutex) ); - SAL_INFO("vcl.gtk", "creating GtkInstance " << pInstance); - - // Create SalData, this does not leak - new GtkSalData( pInstance ); - - return pInstance; - } -} - -#if GTK_CHECK_VERSION(3,0,0) -static VclInputFlags categorizeEvent(const GdkEvent *pEvent) -{ - VclInputFlags nType = VclInputFlags::NONE; - switch( pEvent->type ) - { - case GDK_MOTION_NOTIFY: - case GDK_BUTTON_PRESS: - case GDK_2BUTTON_PRESS: - case GDK_3BUTTON_PRESS: - case GDK_BUTTON_RELEASE: - case GDK_ENTER_NOTIFY: - case GDK_LEAVE_NOTIFY: - case GDK_SCROLL: - nType = VclInputFlags::MOUSE; - break; - case GDK_KEY_PRESS: - // case GDK_KEY_RELEASE: //similar to the X11SalInstance one - nType = VclInputFlags::KEYBOARD; - break; - case GDK_EXPOSE: - nType = VclInputFlags::PAINT; - break; - default: - nType = VclInputFlags::OTHER; - break; - } - return nType; -} -#endif - -GtkInstance::GtkInstance( std::unique_ptr<SalYieldMutex> pMutex ) -#if GTK_CHECK_VERSION(3,0,0) - : SvpSalInstance( std::move(pMutex) ) -#else - : X11SalInstance( std::move(pMutex) ) -#endif - , m_pTimer(nullptr) - , bNeedsInit(true) - , m_pLastCairoFontOptions(nullptr) -{ -} - -//We want to defer initializing gtk until we are after uno has been -//bootstrapped so we can ask the config what the UI language is so that we can -//force that in as $LANGUAGE to get gtk to render widgets RTL if we have a RTL -//UI in a LTR locale -void GtkInstance::AfterAppInit() -{ - EnsureInit(); -} - -void GtkInstance::EnsureInit() -{ - if (!bNeedsInit) - return; - // initialize SalData - GtkSalData *pSalData = GetGtkSalData(); - pSalData->Init(); - GtkSalData::initNWF(); - - InitAtkBridge(); - - ImplSVData* pSVData = ImplGetSVData(); -#ifdef GTK_TOOLKIT_NAME - pSVData->maAppData.mxToolkitName = OUString(GTK_TOOLKIT_NAME); -#elif GTK_CHECK_VERSION(3,0,0) - pSVData->maAppData.mxToolkitName = OUString("gtk3"); -#else - pSVData->maAppData.mxToolkitName = OUString("gtk2"); -#endif - - bNeedsInit = false; -} - -GtkInstance::~GtkInstance() -{ - assert( nullptr == m_pTimer ); - DeInitAtkBridge(); - ResetLastSeenCairoFontOptions(nullptr); -} - -SalFrame* GtkInstance::CreateFrame( SalFrame* pParent, SalFrameStyleFlags nStyle ) -{ - EnsureInit(); - return new GtkSalFrame( pParent, nStyle ); -} - -SalFrame* GtkInstance::CreateChildFrame( SystemParentData* pParentData, SalFrameStyleFlags ) -{ - EnsureInit(); - return new GtkSalFrame( pParentData ); -} - -SalObject* GtkInstance::CreateObject( SalFrame* pParent, SystemWindowData* pWindowData, bool bShow ) -{ - EnsureInit(); -#if !GTK_CHECK_VERSION(3,0,0) - // there is no method to set a visual for a GtkWidget - // so we need the X11SalObject in that case - if( pWindowData ) - return X11SalObject::CreateObject( pParent, pWindowData, bShow ); -#else - (void)pWindowData; - //FIXME: Missing CreateObject functionality ... -#endif - - return new GtkSalObject( static_cast<GtkSalFrame*>(pParent), bShow ); -} - -extern "C" -{ - typedef void*(* getDefaultFnc)(); - typedef void(* addItemFnc)(void *, const char *); -} - -void GtkInstance::AddToRecentDocumentList(const OUString& rFileUrl, const OUString&, const OUString&) -{ - EnsureInit(); - OString sGtkURL; - rtl_TextEncoding aSystemEnc = osl_getThreadTextEncoding(); - if ((aSystemEnc == RTL_TEXTENCODING_UTF8) || !rFileUrl.startsWith( "file://" )) - sGtkURL = OUStringToOString(rFileUrl, RTL_TEXTENCODING_UTF8); - else - { - //Non-utf8 locales are a bad idea if trying to work with non-ascii filenames - //Decode %XX components - OUString sDecodedUri = rtl::Uri::decode(rFileUrl.copy(7), rtl_UriDecodeToIuri, RTL_TEXTENCODING_UTF8); - //Convert back to system locale encoding - OString sSystemUrl = OUStringToOString(sDecodedUri, aSystemEnc); - //Encode to an escaped ASCII-encoded URI - gchar *g_uri = g_filename_to_uri(sSystemUrl.getStr(), nullptr, nullptr); - sGtkURL = OString(g_uri); - g_free(g_uri); - } - GtkRecentManager *manager = gtk_recent_manager_get_default (); - gtk_recent_manager_add_item (manager, sGtkURL.getStr()); -} - -SalInfoPrinter* GtkInstance::CreateInfoPrinter( SalPrinterQueueInfo* pQueueInfo, - ImplJobSetup* pSetupData ) -{ - EnsureInit(); -#if defined ENABLE_GTK_PRINT || GTK_CHECK_VERSION(3,0,0) - mbPrinterInit = true; - // create and initialize SalInfoPrinter - PspSalInfoPrinter* pPrinter = new GtkSalInfoPrinter; - configurePspInfoPrinter(pPrinter, pQueueInfo, pSetupData); - return pPrinter; -#else - return Superclass_t::CreateInfoPrinter( pQueueInfo, pSetupData ); -#endif -} - -std::unique_ptr<SalPrinter> GtkInstance::CreatePrinter( SalInfoPrinter* pInfoPrinter ) -{ - EnsureInit(); -#if defined ENABLE_GTK_PRINT || GTK_CHECK_VERSION(3,0,0) - mbPrinterInit = true; - return std::unique_ptr<SalPrinter>(new GtkSalPrinter( pInfoPrinter )); -#else - return Superclass_t::CreatePrinter( pInfoPrinter ); -#endif -} - -/* - * These methods always occur in pairs - * A ThreadsEnter is followed by a ThreadsLeave - * We need to queue up the recursive lock count - * for each pair, so we can accurately restore - * it later. - */ -thread_local std::stack<sal_uInt32> GtkYieldMutex::yieldCounts; - -void GtkYieldMutex::ThreadsEnter() -{ - acquire(); - if (!yieldCounts.empty()) { - auto n = yieldCounts.top(); - yieldCounts.pop(); - assert(n > 0); - n--; - if (n > 0) - acquire(n); - } -} - -void GtkYieldMutex::ThreadsLeave() -{ - assert(m_nCount != 0); - yieldCounts.push(m_nCount); - release(true); -} - -std::unique_ptr<SalVirtualDevice> GtkInstance::CreateVirtualDevice( SalGraphics *pG, - long &nDX, long &nDY, - DeviceFormat eFormat, - const SystemGraphicsData *pGd ) -{ - EnsureInit(); -#if GTK_CHECK_VERSION(3,0,0) - (void) pGd; - SvpSalGraphics *pSvpSalGraphics = dynamic_cast<SvpSalGraphics*>(pG); - assert(pSvpSalGraphics); - std::unique_ptr<SalVirtualDevice> pNew(new SvpSalVirtualDevice(eFormat, pSvpSalGraphics->getSurface())); - pNew->SetSize( nDX, nDY ); - return pNew; -#else - GtkSalGraphics *pGtkSalGraphics = dynamic_cast<GtkSalGraphics*>(pG); - assert(pGtkSalGraphics); - return CreateX11VirtualDevice(pG, nDX, nDY, eFormat, pGd, - std::make_unique<GtkSalGraphics>(pGtkSalGraphics->GetGtkFrame(), - pGtkSalGraphics->GetGtkWidget(), - pGtkSalGraphics->GetScreenNumber())); -#endif -} - -std::shared_ptr<SalBitmap> GtkInstance::CreateSalBitmap() -{ - EnsureInit(); -#if GTK_CHECK_VERSION(3,0,0) - return SvpSalInstance::CreateSalBitmap();//new SvpSalBitmap(); -#else - return X11SalInstance::CreateSalBitmap(); -#endif -} - -#ifdef ENABLE_GMENU_INTEGRATION - -std::unique_ptr<SalMenu> GtkInstance::CreateMenu( bool bMenuBar, Menu* pVCLMenu ) -{ - EnsureInit(); - GtkSalMenu* pSalMenu = new GtkSalMenu( bMenuBar ); - pSalMenu->SetMenu( pVCLMenu ); - return std::unique_ptr<SalMenu>(pSalMenu); -} - -std::unique_ptr<SalMenuItem> GtkInstance::CreateMenuItem( const SalItemParams & rItemData ) -{ - EnsureInit(); - return std::unique_ptr<SalMenuItem>(new GtkSalMenuItem( &rItemData )); -} - -#else // not ENABLE_GMENU_INTEGRATION - -std::unique_ptr<SalMenu> GtkInstance::CreateMenu( bool, Menu* ) { return nullptr; } -std::unique_ptr<SalMenuItem> GtkInstance::CreateMenuItem( const SalItemParams & ) { return nullptr; } - -#endif - -SalTimer* GtkInstance::CreateSalTimer() -{ - EnsureInit(); - assert( nullptr == m_pTimer ); - if ( nullptr == m_pTimer ) - m_pTimer = new GtkSalTimer(); - return m_pTimer; -} - -void GtkInstance::RemoveTimer () -{ - EnsureInit(); - m_pTimer = nullptr; -} - -bool GtkInstance::DoYield(bool bWait, bool bHandleAllCurrentEvents) -{ - EnsureInit(); - return GetGtkSalData()->Yield( bWait, bHandleAllCurrentEvents ); -} - -bool GtkInstance::IsTimerExpired() -{ - EnsureInit(); - return (m_pTimer && m_pTimer->Expired()); -} - -bool GtkInstance::AnyInput( VclInputFlags nType ) -{ - EnsureInit(); - if( (nType & VclInputFlags::TIMER) && IsTimerExpired() ) - return true; -#if !GTK_CHECK_VERSION(3,0,0) - bool bRet = X11SalInstance::AnyInput(nType); -#else - if (!gdk_events_pending()) - return false; - - if (nType == VCL_INPUT_ANY) - return true; - - bool bRet = false; - std::stack<GdkEvent*> aEvents; - GdkEvent *pEvent = nullptr; - while ((pEvent = gdk_event_get())) - { - aEvents.push(pEvent); - VclInputFlags nEventType = categorizeEvent(pEvent); - if ( (nEventType & nType) || ( nEventType == VclInputFlags::NONE && (nType & VclInputFlags::OTHER) ) ) - { - bRet = true; - break; - } - } - - while (!aEvents.empty()) - { - pEvent = aEvents.top(); - gdk_event_put(pEvent); - gdk_event_free(pEvent); - aEvents.pop(); - } -#endif - return bRet; -} - -std::unique_ptr<GenPspGraphics> GtkInstance::CreatePrintGraphics() -{ - EnsureInit(); - return std::make_unique<GenPspGraphics>(); -} - -std::shared_ptr<vcl::unx::GtkPrintWrapper> const & -GtkInstance::getPrintWrapper() const -{ - if (!m_xPrintWrapper) - m_xPrintWrapper.reset(new vcl::unx::GtkPrintWrapper); - return m_xPrintWrapper; -} - -const cairo_font_options_t* GtkInstance::GetCairoFontOptions() -{ - const cairo_font_options_t* pCairoFontOptions = gdk_screen_get_font_options(gdk_screen_get_default()); - if (!m_pLastCairoFontOptions && pCairoFontOptions) - m_pLastCairoFontOptions = cairo_font_options_copy(pCairoFontOptions); - return pCairoFontOptions; -} - -const cairo_font_options_t* GtkInstance::GetLastSeenCairoFontOptions() const -{ - return m_pLastCairoFontOptions; -} - -void GtkInstance::ResetLastSeenCairoFontOptions(const cairo_font_options_t* pCairoFontOptions) -{ - if (m_pLastCairoFontOptions) - cairo_font_options_destroy(m_pLastCairoFontOptions); - if (pCairoFontOptions) - m_pLastCairoFontOptions = cairo_font_options_copy(pCairoFontOptions); - else - m_pLastCairoFontOptions = nullptr; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/gtkobject.cxx b/vcl/unx/gtk/gtkobject.cxx deleted file mode 100644 index 38302c60ef74..000000000000 --- a/vcl/unx/gtk/gtkobject.cxx +++ /dev/null @@ -1,192 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifdef AIX -#define _LINUX_SOURCE_COMPAT -#include <sys/timer.h> -#undef _LINUX_SOURCE_COMPAT -#endif - -#include <unx/gtk/gtkobject.hxx> -#include <unx/gtk/gtkframe.hxx> -#include <unx/gtk/gtkdata.hxx> -#include <unx/gtk/gtkinst.hxx> -#include <unx/gtk/gtkgdi.hxx> - -GtkSalObject::GtkSalObject( GtkSalFrame* pParent, bool bShow ) - : m_pSocket( nullptr ), - m_pRegion( nullptr ) -{ - if( !pParent ) - return; - - // our plug window - m_pSocket = gtk_drawing_area_new(); - Show( bShow ); - // insert into container - gtk_fixed_put( pParent->getFixedContainer(), - m_pSocket, - 0, 0 ); - // realize so we can get a window id - gtk_widget_realize( m_pSocket ); - - // make it transparent; some plugins may not insert - // their own window here but use the socket window itself - gtk_widget_set_app_paintable( m_pSocket, TRUE ); - - // system data - m_aSystemData.nSize = sizeof( SystemEnvData ); - SalDisplay* pDisp = vcl_sal::getSalDisplay(GetGenericUnixSalData()); - m_aSystemData.pDisplay = pDisp->GetDisplay(); - m_aSystemData.pVisual = pDisp->GetVisual(pParent->getXScreenNumber()).GetVisual(); - m_aSystemData.aWindow = GDK_WINDOW_XWINDOW(widget_get_window(m_pSocket)); - m_aSystemData.aShellWindow = GDK_WINDOW_XWINDOW(widget_get_window(GTK_WIDGET(pParent->getWindow()))); - m_aSystemData.pSalFrame = nullptr; - m_aSystemData.pWidget = m_pSocket; - m_aSystemData.nScreen = pParent->getXScreenNumber().getXScreen(); - m_aSystemData.pToolkit = "gtk2"; - m_aSystemData.pPlatformName = "xcb"; - - g_signal_connect( G_OBJECT(m_pSocket), "button-press-event", G_CALLBACK(signalButton), this ); - g_signal_connect( G_OBJECT(m_pSocket), "button-release-event", G_CALLBACK(signalButton), this ); - g_signal_connect( G_OBJECT(m_pSocket), "focus-in-event", G_CALLBACK(signalFocus), this ); - g_signal_connect( G_OBJECT(m_pSocket), "focus-out-event", G_CALLBACK(signalFocus), this ); - g_signal_connect( G_OBJECT(m_pSocket), "destroy", G_CALLBACK(signalDestroy), this ); - - // #i59255# necessary due to sync effects with java child windows - pParent->Flush(); - -} - -GtkSalObject::~GtkSalObject() -{ - if( m_pRegion ) - { - gdk_region_destroy( m_pRegion ); - } - if( m_pSocket ) - { - // remove socket from parent frame's fixed container - gtk_container_remove( GTK_CONTAINER(gtk_widget_get_parent(m_pSocket)), - m_pSocket ); - // get rid of the socket - // actually the gtk_container_remove should let the ref count - // of the socket sink to 0 and destroy it (see signalDestroy) - // this is just a sanity check - if( m_pSocket ) - gtk_widget_destroy( m_pSocket ); - } -} - -void GtkSalObject::ResetClipRegion() -{ - if( m_pSocket ) - gdk_window_shape_combine_region( widget_get_window(m_pSocket), nullptr, 0, 0 ); -} - -void GtkSalObject::BeginSetClipRegion( sal_uInt32 ) -{ - if( m_pRegion ) - gdk_region_destroy( m_pRegion ); - m_pRegion = gdk_region_new(); -} - -void GtkSalObject::UnionClipRegion( long nX, long nY, long nWidth, long nHeight ) -{ - GdkRectangle aRect; - aRect.x = nX; - aRect.y = nY; - aRect.width = nWidth; - aRect.height = nHeight; - - gdk_region_union_with_rect( m_pRegion, &aRect ); -} - -void GtkSalObject::EndSetClipRegion() -{ - if( m_pSocket ) - gdk_window_shape_combine_region( widget_get_window(m_pSocket), m_pRegion, 0, 0 ); -} - -void GtkSalObject::SetPosSize( long nX, long nY, long nWidth, long nHeight ) -{ - if( m_pSocket ) - { - GtkFixed* pContainer = GTK_FIXED(gtk_widget_get_parent(m_pSocket)); - gtk_fixed_move( pContainer, m_pSocket, nX, nY ); - gtk_widget_set_size_request( m_pSocket, nWidth, nHeight ); - gtk_container_resize_children( GTK_CONTAINER(pContainer) ); - } -} - -void GtkSalObject::Show( bool bVisible ) -{ - if( m_pSocket ) - { - if( bVisible ) - gtk_widget_show( m_pSocket ); - else - gtk_widget_hide( m_pSocket ); - } -} - -const SystemEnvData* GtkSalObject::GetSystemData() const -{ - return &m_aSystemData; -} - -gboolean GtkSalObject::signalButton( GtkWidget*, GdkEventButton* pEvent, gpointer object ) -{ - GtkSalObject* pThis = static_cast<GtkSalObject*>(object); - - if( pEvent->type == GDK_BUTTON_PRESS ) - { - pThis->CallCallback( SalObjEvent::ToTop ); - } - - return FALSE; -} - -gboolean GtkSalObject::signalFocus( GtkWidget*, GdkEventFocus* pEvent, gpointer object ) -{ - GtkSalObject* pThis = static_cast<GtkSalObject*>(object); - - pThis->CallCallback( pEvent->in ? SalObjEvent::GetFocus : SalObjEvent::LoseFocus ); - - return FALSE; -} - -void GtkSalObject::signalDestroy( GtkWidget* pObj, gpointer object ) -{ - GtkSalObject* pThis = static_cast<GtkSalObject*>(object); - if( pObj == pThis->m_pSocket ) - { - pThis->m_pSocket = nullptr; - } -} - -void GtkSalObject::SetForwardKey( bool bEnable ) -{ - if( bEnable ) - gtk_widget_add_events( GTK_WIDGET( m_pSocket ), GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE ); - else - gtk_widget_set_events( GTK_WIDGET( m_pSocket ), ~(GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE) & gtk_widget_get_events( GTK_WIDGET( m_pSocket ) ) ); -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/gtkprintwrapper.cxx b/vcl/unx/gtk/gtkprintwrapper.cxx deleted file mode 100644 index 7e2241304f26..000000000000 --- a/vcl/unx/gtk/gtkprintwrapper.cxx +++ /dev/null @@ -1,349 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -#include <cassert> - -#include <rtl/ustring.hxx> - -#include <unx/gtk/gtkprintwrapper.hxx> - -namespace vcl -{ -namespace unx -{ - -#if !GTK_CHECK_VERSION(3,0,0) - -GtkPrintWrapper::GtkPrintWrapper() - : m_page_setup_new(nullptr) - , m_print_job_new(nullptr) - , m_print_job_send(nullptr) - , m_print_job_set_source_file(nullptr) - , m_print_settings_get(nullptr) - , m_print_settings_get_collate(nullptr) - , m_print_settings_set_collate(nullptr) - , m_print_settings_get_n_copies(nullptr) - , m_print_settings_set_n_copies(nullptr) - , m_print_settings_get_page_ranges(nullptr) - , m_print_settings_set_print_pages(nullptr) - , m_print_unix_dialog_new(nullptr) - , m_print_unix_dialog_add_custom_tab(nullptr) - , m_print_unix_dialog_get_selected_printer(nullptr) - , m_print_unix_dialog_set_manual_capabilities(nullptr) - , m_print_unix_dialog_get_settings(nullptr) - , m_print_unix_dialog_set_settings(nullptr) - , m_print_unix_dialog_set_support_selection(nullptr) - , m_print_unix_dialog_set_has_selection(nullptr) -{ - impl_load(); -} - -#else - -GtkPrintWrapper::GtkPrintWrapper() -{ -} - -#endif - -GtkPrintWrapper::~GtkPrintWrapper() -{ -} - -#if !GTK_CHECK_VERSION(3,0,0) - -void GtkPrintWrapper::impl_load() -{ - m_aModule.load("libgtk-x11-2.0.so.0"); - if (!m_aModule.is()) - m_aModule.load("libgtk-x11-2.0.so"); - if (!m_aModule.is()) - return; - - m_page_setup_new = reinterpret_cast<page_setup_new_t>(m_aModule.getFunctionSymbol("gtk_page_setup_new")); - m_print_job_new = reinterpret_cast<print_job_new_t>(m_aModule.getFunctionSymbol("gtk_print_job_new")); - m_print_job_send = reinterpret_cast<print_job_send_t>(m_aModule.getFunctionSymbol("gtk_print_job_send")); - m_print_job_set_source_file = reinterpret_cast<print_job_set_source_file_t>(m_aModule.getFunctionSymbol("gtk_print_job_set_source_file")); - m_print_settings_get = reinterpret_cast<print_settings_get_t>(m_aModule.getFunctionSymbol("gtk_print_settings_get")); - m_print_settings_get_collate = reinterpret_cast<print_settings_get_collate_t>(m_aModule.getFunctionSymbol("gtk_print_settings_get_collate")); - m_print_settings_set_collate = reinterpret_cast<print_settings_set_collate_t>(m_aModule.getFunctionSymbol("gtk_print_settings_set_collate")); - m_print_settings_get_n_copies = reinterpret_cast<print_settings_get_n_copies_t>(m_aModule.getFunctionSymbol("gtk_print_settings_get_n_copies")); - m_print_settings_set_n_copies = reinterpret_cast<print_settings_set_n_copies_t>(m_aModule.getFunctionSymbol("gtk_print_settings_set_n_copies")); - m_print_settings_get_page_ranges = reinterpret_cast<print_settings_get_page_ranges_t>(m_aModule.getFunctionSymbol("gtk_print_settings_get_page_ranges")); - m_print_settings_set_print_pages = reinterpret_cast<print_settings_set_print_pages_t>(m_aModule.getFunctionSymbol("gtk_print_settings_set_print_pages")); - m_print_unix_dialog_new = reinterpret_cast<print_unix_dialog_new_t>(m_aModule.getFunctionSymbol("gtk_print_unix_dialog_new")); - m_print_unix_dialog_add_custom_tab = reinterpret_cast<print_unix_dialog_add_custom_tab_t>(m_aModule.getFunctionSymbol("gtk_print_unix_dialog_add_custom_tab")); - m_print_unix_dialog_get_selected_printer = reinterpret_cast<print_unix_dialog_get_selected_printer_t>(m_aModule.getFunctionSymbol("gtk_print_unix_dialog_get_selected_printer")); - m_print_unix_dialog_set_manual_capabilities = reinterpret_cast<print_unix_dialog_set_manual_capabilities_t>(m_aModule.getFunctionSymbol("gtk_print_unix_dialog_set_manual_capabilities")); - m_print_unix_dialog_get_settings = reinterpret_cast<print_unix_dialog_get_settings_t>(m_aModule.getFunctionSymbol("gtk_print_unix_dialog_get_settings")); - m_print_unix_dialog_set_settings = reinterpret_cast<print_unix_dialog_set_settings_t>(m_aModule.getFunctionSymbol("gtk_print_unix_dialog_set_settings")); - m_print_unix_dialog_set_support_selection = reinterpret_cast<print_unix_dialog_set_support_selection_t>(m_aModule.getFunctionSymbol("gtk_print_unix_dialog_set_support_selection")); - m_print_unix_dialog_set_has_selection = reinterpret_cast<print_unix_dialog_set_has_selection_t>(m_aModule.getFunctionSymbol("gtk_print_unix_dialog_set_has_selection")); -} - -#endif - -bool GtkPrintWrapper::supportsPrinting() const -{ -#if !GTK_CHECK_VERSION(3,0,0) - return - m_page_setup_new - && m_print_job_new - && m_print_job_send - && m_print_job_set_source_file - && m_print_settings_get - && m_print_settings_get_collate - && m_print_settings_set_collate - && m_print_settings_get_n_copies - && m_print_settings_set_n_copies - && m_print_settings_get_page_ranges - && m_print_settings_set_print_pages - && m_print_unix_dialog_new - && m_print_unix_dialog_add_custom_tab - && m_print_unix_dialog_get_selected_printer - && m_print_unix_dialog_set_manual_capabilities - && m_print_unix_dialog_get_settings - && m_print_unix_dialog_set_settings - ; -#else - (void) this; // loplugin:staticmethods - return true; -#endif -} - -bool GtkPrintWrapper::supportsPrintSelection() const -{ -#if !GTK_CHECK_VERSION(3,0,0) - return - supportsPrinting() - && m_print_unix_dialog_set_support_selection - && m_print_unix_dialog_set_has_selection - ; -#else - (void) this; // loplugin:staticmethods - return true; -#endif -} - -GtkPageSetup* GtkPrintWrapper::page_setup_new() const -{ -#if !GTK_CHECK_VERSION(3,0,0) - assert(m_page_setup_new); - return (*m_page_setup_new)(); -#else - (void) this; // loplugin:staticmethods - return gtk_page_setup_new(); -#endif -} - -GtkPrintJob* GtkPrintWrapper::print_job_new(const gchar* title, GtkPrinter* printer, GtkPrintSettings* settings, GtkPageSetup* page_setup) const -{ -#if !GTK_CHECK_VERSION(3,0,0) - assert(m_print_job_new); - return (*m_print_job_new)(title, printer, settings, page_setup); -#else - (void) this; // loplugin:staticmethods - return gtk_print_job_new(title, printer, settings, page_setup); -#endif -} - -void GtkPrintWrapper::print_job_send(GtkPrintJob* job, GtkPrintJobCompleteFunc callback, gpointer user_data, GDestroyNotify dnotify) const -{ -#if !GTK_CHECK_VERSION(3,0,0) - assert(m_print_job_send); - (*m_print_job_send)(job, callback, user_data, dnotify); -#else - (void) this; // loplugin:staticmethods - gtk_print_job_send(job, callback, user_data, dnotify); -#endif -} - -gboolean GtkPrintWrapper::print_job_set_source_file(GtkPrintJob* job, const gchar* filename, GError** error) const -{ -#if !GTK_CHECK_VERSION(3,0,0) - assert(m_print_job_set_source_file); - return (*m_print_job_set_source_file)(job, filename, error); -#else - (void) this; // loplugin:staticmethods - return gtk_print_job_set_source_file(job, filename, error); -#endif -} - -const gchar* GtkPrintWrapper::print_settings_get(GtkPrintSettings* settings, const gchar* key) const -{ -#if !GTK_CHECK_VERSION(3,0,0) - assert(m_print_settings_get); - return (*m_print_settings_get)(settings, key); -#else - (void) this; // loplugin:staticmethods - return gtk_print_settings_get(settings, key); -#endif -} - -gboolean GtkPrintWrapper::print_settings_get_collate(GtkPrintSettings* settings) const -{ -#if !GTK_CHECK_VERSION(3,0,0) - assert(m_print_settings_get_collate); - return (*m_print_settings_get_collate)(settings); -#else - (void) this; // loplugin:staticmethods - return gtk_print_settings_get_collate(settings); -#endif -} - -void GtkPrintWrapper::print_settings_set_collate(GtkPrintSettings* settings, gboolean collate) const -{ -#if !GTK_CHECK_VERSION(3,0,0) - assert(m_print_settings_set_collate); - (*m_print_settings_set_collate)(settings, collate); -#else - (void) this; // loplugin:staticmethods - gtk_print_settings_set_collate(settings, collate); -#endif -} - -gint GtkPrintWrapper::print_settings_get_n_copies(GtkPrintSettings* settings) const -{ -#if !GTK_CHECK_VERSION(3,0,0) - assert(m_print_settings_get_n_copies); - return (*m_print_settings_get_n_copies)(settings); -#else - (void) this; // loplugin:staticmethods - return gtk_print_settings_get_n_copies(settings); -#endif -} - -void GtkPrintWrapper::print_settings_set_n_copies(GtkPrintSettings* settings, gint num_copies) const -{ -#if !GTK_CHECK_VERSION(3,0,0) - assert(m_print_settings_set_n_copies); - (*m_print_settings_set_n_copies)(settings, num_copies); -#else - (void) this; // loplugin:staticmethods - gtk_print_settings_set_n_copies(settings, num_copies); -#endif -} - -GtkPageRange* GtkPrintWrapper::print_settings_get_page_ranges(GtkPrintSettings* settings, gint* num_ranges) const -{ -#if !GTK_CHECK_VERSION(3,0,0) - assert(m_print_settings_get_page_ranges); - return (*m_print_settings_get_page_ranges)(settings, num_ranges); -#else - (void) this; // loplugin:staticmethods - return gtk_print_settings_get_page_ranges(settings, num_ranges); -#endif -} - -void GtkPrintWrapper::print_settings_set_print_pages(GtkPrintSettings* settings, GtkPrintPages pages) const -{ -#if !GTK_CHECK_VERSION(3,0,0) - assert(m_print_settings_set_print_pages); - (*m_print_settings_set_print_pages)(settings, pages); -#else - (void) this; // loplugin:staticmethods - gtk_print_settings_set_print_pages(settings, pages); -#endif -} - -GtkWidget* GtkPrintWrapper::print_unix_dialog_new() const -{ -#if !GTK_CHECK_VERSION(3,0,0) - assert(m_print_unix_dialog_new); - return (*m_print_unix_dialog_new)(nullptr, nullptr); -#else - (void) this; // loplugin:staticmethods - return gtk_print_unix_dialog_new(nullptr, nullptr); -#endif -} - -void GtkPrintWrapper::print_unix_dialog_add_custom_tab(GtkPrintUnixDialog* dialog, GtkWidget* child, GtkWidget* tab_label) const -{ -#if !GTK_CHECK_VERSION(3,0,0) - assert(m_print_unix_dialog_add_custom_tab); - (*m_print_unix_dialog_add_custom_tab)(dialog, child, tab_label); -#else - (void) this; // loplugin:staticmethods - gtk_print_unix_dialog_add_custom_tab(dialog, child, tab_label); -#endif -} - -GtkPrinter* GtkPrintWrapper::print_unix_dialog_get_selected_printer(GtkPrintUnixDialog* dialog) const -{ - GtkPrinter* pRet = nullptr; -#if !GTK_CHECK_VERSION(3,0,0) - assert(m_print_unix_dialog_get_selected_printer); - pRet = (*m_print_unix_dialog_get_selected_printer)(dialog); -#else - (void) this; // loplugin:staticmethods - pRet = gtk_print_unix_dialog_get_selected_printer(dialog); -#endif - g_object_ref(G_OBJECT(pRet)); - return pRet; -} - -void GtkPrintWrapper::print_unix_dialog_set_manual_capabilities(GtkPrintUnixDialog* dialog, GtkPrintCapabilities capabilities) const -{ -#if !GTK_CHECK_VERSION(3,0,0) - assert(m_print_unix_dialog_set_manual_capabilities); - (*m_print_unix_dialog_set_manual_capabilities)(dialog, capabilities); -#else - (void) this; // loplugin:staticmethods - gtk_print_unix_dialog_set_manual_capabilities(dialog, capabilities); -#endif -} - -GtkPrintSettings* GtkPrintWrapper::print_unix_dialog_get_settings(GtkPrintUnixDialog* dialog) const -{ -#if !GTK_CHECK_VERSION(3,0,0) - assert(m_print_unix_dialog_get_settings); - return (*m_print_unix_dialog_get_settings)(dialog); -#else - (void) this; // loplugin:staticmethods - return gtk_print_unix_dialog_get_settings(dialog); -#endif -} - -void GtkPrintWrapper::print_unix_dialog_set_settings(GtkPrintUnixDialog* dialog, GtkPrintSettings* settings) const -{ -#if !GTK_CHECK_VERSION(3,0,0) - assert(m_print_unix_dialog_set_settings); - (*m_print_unix_dialog_set_settings)(dialog, settings); -#else - (void) this; // loplugin:staticmethods - gtk_print_unix_dialog_set_settings(dialog, settings); -#endif -} - -void GtkPrintWrapper::print_unix_dialog_set_support_selection(GtkPrintUnixDialog* dialog, gboolean support_selection) const -{ -#if !GTK_CHECK_VERSION(3,0,0) - assert(m_print_unix_dialog_set_support_selection); - (*m_print_unix_dialog_set_support_selection)(dialog, support_selection); -#else - (void) this; // loplugin:staticmethods - gtk_print_unix_dialog_set_support_selection(dialog, support_selection); -#endif -} - -void GtkPrintWrapper::print_unix_dialog_set_has_selection(GtkPrintUnixDialog* dialog, gboolean has_selection) const -{ -#if !GTK_CHECK_VERSION(3,0,0) - assert(m_print_unix_dialog_set_has_selection); - (*m_print_unix_dialog_set_has_selection)(dialog, has_selection); -#else - (void) this; // loplugin:staticmethods - gtk_print_unix_dialog_set_has_selection(dialog, has_selection); -#endif -} - -} -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/gtksalframe.cxx b/vcl/unx/gtk/gtksalframe.cxx deleted file mode 100644 index 2601d7d675fb..000000000000 --- a/vcl/unx/gtk/gtksalframe.cxx +++ /dev/null @@ -1,3606 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include <unx/gtk/gtkframe.hxx> -#include <unx/gtk/gtkdata.hxx> -#include <unx/gtk/gtkinst.hxx> -#include <unx/gtk/gtkgdi.hxx> -#include <unx/gtk/gtksalmenu.hxx> -#include <vcl/keycodes.hxx> -#include <vcl/layout.hxx> -#include <unx/wmadaptor.hxx> -#include <unx/sm.hxx> -#include <unx/salbmp.h> -#include <unx/genprn.h> -#include <unx/geninst.h> -#include <headless/svpgdi.hxx> -#include <osl/file.hxx> -#include <rtl/bootstrap.hxx> -#include <rtl/process.h> -#include <sal/log.hxx> -#include <tools/diagnose_ex.h> -#include <vcl/floatwin.hxx> -#include <vcl/svapp.hxx> -#include <vcl/window.hxx> -#include <vcl/settings.hxx> -#include <vcl/opengl/OpenGLHelper.hxx> - -#include <config_gio.h> - -#include <unx/x11/xlimits.hxx> -#if defined ENABLE_GMENU_INTEGRATION // defined in gtksalmenu.hxx above -# include <unx/gtk/hudawareness.h> -#endif - -#include <gtk/gtk.h> -#include <gdk/gdkx.h> -#include <X11/Xatom.h> - -#include <dlfcn.h> -#include <window.h> -#include <strings.hrc> -#include <bitmaps.hlst> -#include <sal/macros.h> - -#include <basegfx/range/b2ibox.hxx> -#include <basegfx/vector/b2ivector.hxx> - -#include <algorithm> -#include <glib/gprintf.h> - -#if OSL_DEBUG_LEVEL > 1 -# include <cstdio> -#endif - -#include <com/sun/star/accessibility/XAccessibleContext.hpp> -#include <com/sun/star/accessibility/XAccessibleEditableText.hpp> - -#include <config_folders.h> - -#define IS_WIDGET_REALIZED GTK_WIDGET_REALIZED -#define IS_WIDGET_MAPPED GTK_WIDGET_MAPPED - -using namespace com::sun::star; - -int GtkSalFrame::m_nFloats = 0; - -#if defined ENABLE_GMENU_INTEGRATION -static GDBusConnection* pSessionBus = nullptr; -#endif - -sal_uInt16 GtkSalFrame::GetKeyModCode( guint state ) -{ - sal_uInt16 nCode = 0; - if( state & GDK_SHIFT_MASK ) - nCode |= KEY_SHIFT; - if( state & GDK_CONTROL_MASK ) - nCode |= KEY_MOD1; - if( state & GDK_MOD1_MASK ) - nCode |= KEY_MOD2; - - // Map Meta/Super keys to MOD3 modifier on all Unix systems - // except macOS - if ( (state & GDK_META_MASK ) || ( state & GDK_SUPER_MASK ) ) - nCode |= KEY_MOD3; - return nCode; -} - -sal_uInt16 GtkSalFrame::GetMouseModCode( guint state ) -{ - sal_uInt16 nCode = GetKeyModCode( state ); - if( state & GDK_BUTTON1_MASK ) - nCode |= MOUSE_LEFT; - if( state & GDK_BUTTON2_MASK ) - nCode |= MOUSE_MIDDLE; - if( state & GDK_BUTTON3_MASK ) - nCode |= MOUSE_RIGHT; - - return nCode; -} - -sal_uInt16 GtkSalFrame::GetKeyCode(guint keyval) -{ - sal_uInt16 nCode = 0; - if( keyval >= GDK_KEY_0 && keyval <= GDK_KEY_9 ) - nCode = KEY_0 + (keyval-GDK_KEY_0); - else if( keyval >= GDK_KEY_KP_0 && keyval <= GDK_KEY_KP_9 ) - nCode = KEY_0 + (keyval-GDK_KEY_KP_0); - else if( keyval >= GDK_KEY_A && keyval <= GDK_KEY_Z ) - nCode = KEY_A + (keyval-GDK_KEY_A ); - else if( keyval >= GDK_KEY_a && keyval <= GDK_KEY_z ) - nCode = KEY_A + (keyval-GDK_KEY_a ); - else if( keyval >= GDK_KEY_F1 && keyval <= GDK_KEY_F26 ) - // KEY_F26 is the last function key known to keycodes.hxx - { - if( GetGtkSalData()->GetGtkDisplay()->IsNumLockFromXS() ) - { - nCode = KEY_F1 + (keyval-GDK_KEY_F1); - } - else - { - switch( keyval ) - { - // - - - - - Sun keyboard, see vcl/unx/source/app/saldisp.cxx - // although GDK_KEY_F1 ... GDK_KEY_L10 are known to - // gdk/gdkkeysyms.h, they are unlikely to be generated - // except possibly by Solaris systems - // this whole section needs review - case GDK_KEY_L2: - if( GetGtkSalData()->GetGtkDisplay()->GetServerVendor() == vendor_sun ) - nCode = KEY_REPEAT; - else - nCode = KEY_F12; - break; - case GDK_KEY_L3: nCode = KEY_PROPERTIES; break; - case GDK_KEY_L4: nCode = KEY_UNDO; break; - case GDK_KEY_L6: nCode = KEY_COPY; break; // KEY_F16 - case GDK_KEY_L8: nCode = KEY_PASTE; break; // KEY_F18 - case GDK_KEY_L10: nCode = KEY_CUT; break; // KEY_F20 - default: - nCode = KEY_F1 + (keyval-GDK_KEY_F1); break; - } - } - } - else - { - switch( keyval ) - { - case GDK_KEY_KP_Down: - case GDK_KEY_Down: nCode = KEY_DOWN; break; - case GDK_KEY_KP_Up: - case GDK_KEY_Up: nCode = KEY_UP; break; - case GDK_KEY_KP_Left: - case GDK_KEY_Left: nCode = KEY_LEFT; break; - case GDK_KEY_KP_Right: - case GDK_KEY_Right: nCode = KEY_RIGHT; break; - case GDK_KEY_KP_Begin: - case GDK_KEY_KP_Home: - case GDK_KEY_Begin: - case GDK_KEY_Home: nCode = KEY_HOME; break; - case GDK_KEY_KP_End: - case GDK_KEY_End: nCode = KEY_END; break; - case GDK_KEY_KP_Page_Up: - case GDK_KEY_Page_Up: nCode = KEY_PAGEUP; break; - case GDK_KEY_KP_Page_Down: - case GDK_KEY_Page_Down: nCode = KEY_PAGEDOWN; break; - case GDK_KEY_KP_Enter: - case GDK_KEY_Return: nCode = KEY_RETURN; break; - case GDK_KEY_Escape: nCode = KEY_ESCAPE; break; - case GDK_KEY_ISO_Left_Tab: - case GDK_KEY_KP_Tab: - case GDK_KEY_Tab: nCode = KEY_TAB; break; - case GDK_KEY_BackSpace: nCode = KEY_BACKSPACE; break; - case GDK_KEY_KP_Space: - case GDK_KEY_space: nCode = KEY_SPACE; break; - case GDK_KEY_KP_Insert: - case GDK_KEY_Insert: nCode = KEY_INSERT; break; - case GDK_KEY_KP_Delete: - case GDK_KEY_Delete: nCode = KEY_DELETE; break; - case GDK_KEY_plus: - case GDK_KEY_KP_Add: nCode = KEY_ADD; break; - case GDK_KEY_minus: - case GDK_KEY_KP_Subtract: nCode = KEY_SUBTRACT; break; - case GDK_KEY_asterisk: - case GDK_KEY_KP_Multiply: nCode = KEY_MULTIPLY; break; - case GDK_KEY_slash: - case GDK_KEY_KP_Divide: nCode = KEY_DIVIDE; break; - case GDK_KEY_period: nCode = KEY_POINT; break; - case GDK_KEY_decimalpoint: nCode = KEY_POINT; break; - case GDK_KEY_comma: nCode = KEY_COMMA; break; - case GDK_KEY_less: nCode = KEY_LESS; break; - case GDK_KEY_greater: nCode = KEY_GREATER; break; - case GDK_KEY_KP_Equal: - case GDK_KEY_equal: nCode = KEY_EQUAL; break; - case GDK_KEY_Find: nCode = KEY_FIND; break; - case GDK_KEY_Menu: nCode = KEY_CONTEXTMENU;break; - case GDK_KEY_Help: nCode = KEY_HELP; break; - case GDK_KEY_Undo: nCode = KEY_UNDO; break; - case GDK_KEY_Redo: nCode = KEY_REPEAT; break; - // on a sun keyboard this actually is usually SunXK_Stop = 0x0000FF69 (XK_Cancel), - // but VCL doesn't have a key definition for that - case GDK_KEY_Cancel: nCode = KEY_F11; break; - case GDK_KEY_KP_Decimal: - case GDK_KEY_KP_Separator: nCode = KEY_DECIMAL; break; - case GDK_KEY_asciitilde: nCode = KEY_TILDE; break; - case GDK_KEY_leftsinglequotemark: - case GDK_KEY_quoteleft: nCode = KEY_QUOTELEFT; break; - case GDK_KEY_bracketleft: nCode = KEY_BRACKETLEFT; break; - case GDK_KEY_bracketright: nCode = KEY_BRACKETRIGHT; break; - case GDK_KEY_semicolon: nCode = KEY_SEMICOLON; break; - case GDK_KEY_quoteright: nCode = KEY_QUOTERIGHT; break; - // some special cases, also see saldisp.cxx - // - - - - - - - - - - - - - Apollo - - - - - - - - - - - - - 0x1000 - // These can be found in ap_keysym.h - case 0x1000FF02: // apXK_Copy - nCode = KEY_COPY; - break; - case 0x1000FF03: // apXK_Cut - nCode = KEY_CUT; - break; - case 0x1000FF04: // apXK_Paste - nCode = KEY_PASTE; - break; - case 0x1000FF14: // apXK_Repeat - nCode = KEY_REPEAT; - break; - // Exit, Save - // - - - - - - - - - - - - - - D E C - - - - - - - - - - - - - 0x1000 - // These can be found in DECkeysym.h - case 0x1000FF00: - nCode = KEY_DELETE; - break; - // - - - - - - - - - - - - - - H P - - - - - - - - - - - - - 0x1000 - // These can be found in HPkeysym.h - case 0x1000FF73: // hpXK_DeleteChar - nCode = KEY_DELETE; - break; - case 0x1000FF74: // hpXK_BackTab - case 0x1000FF75: // hpXK_KP_BackTab - nCode = KEY_TAB; - break; - // - - - - - - - - - - - - - - I B M - - - - - - - - - - - - - - // - - - - - - - - - - - - - - O S F - - - - - - - - - - - - - 0x1004 - // These also can be found in HPkeysym.h - case 0x1004FF02: // osfXK_Copy - nCode = KEY_COPY; - break; - case 0x1004FF03: // osfXK_Cut - nCode = KEY_CUT; - break; - case 0x1004FF04: // osfXK_Paste - nCode = KEY_PASTE; - break; - case 0x1004FF07: // osfXK_BackTab - nCode = KEY_TAB; - break; - case 0x1004FF08: // osfXK_BackSpace - nCode = KEY_BACKSPACE; - break; - case 0x1004FF1B: // osfXK_Escape - nCode = KEY_ESCAPE; - break; - // Up, Down, Left, Right, PageUp, PageDown - // - - - - - - - - - - - - - - S C O - - - - - - - - - - - - - - // - - - - - - - - - - - - - - S G I - - - - - - - - - - - - - 0x1007 - // - - - - - - - - - - - - - - S N I - - - - - - - - - - - - - - // - - - - - - - - - - - - - - S U N - - - - - - - - - - - - - 0x1005 - // These can be found in Sunkeysym.h - case 0x1005FF10: // SunXK_F36 - nCode = KEY_F11; - break; - case 0x1005FF11: // SunXK_F37 - nCode = KEY_F12; - break; - case 0x1005FF70: // SunXK_Props - nCode = KEY_PROPERTIES; - break; - case 0x1005FF71: // SunXK_Front - nCode = KEY_FRONT; - break; - case 0x1005FF72: // SunXK_Copy - nCode = KEY_COPY; - break; - case 0x1005FF73: // SunXK_Open - nCode = KEY_OPEN; - break; - case 0x1005FF74: // SunXK_Paste - nCode = KEY_PASTE; - break; - case 0x1005FF75: // SunXK_Cut - nCode = KEY_CUT; - break; - // - - - - - - - - - - - - - X F 8 6 - - - - - - - - - - - - - 0x1008 - // These can be found in XF86keysym.h - // but more importantly they are also available GTK/Gdk version 3 - // and hence are already provided in gdk/gdkkeysyms.h, and hence - // in gdk/gdk.h - case GDK_KEY_Copy: nCode = KEY_COPY; break; // 0x1008ff57 - case GDK_KEY_Cut: nCode = KEY_CUT; break; // 0x1008ff58 - case GDK_KEY_Open: nCode = KEY_OPEN; break; // 0x1008ff6b - case GDK_KEY_Paste: nCode = KEY_PASTE; break; // 0x1008ff6d - } - } - - return nCode; -} - -guint GtkSalFrame::GetKeyValFor(GdkKeymap* pKeyMap, guint16 hardware_keycode, guint8 group) -{ - guint updated_keyval = 0; - gdk_keymap_translate_keyboard_state(pKeyMap, hardware_keycode, - GdkModifierType(0), group, &updated_keyval, nullptr, nullptr, nullptr); - return updated_keyval; -} - -// F10 means either KEY_F10 or KEY_MENU, which has to be decided -// in the independent part. -struct KeyAlternate -{ - sal_uInt16 nKeyCode; - sal_Unicode nCharCode; - KeyAlternate() : nKeyCode( 0 ), nCharCode( 0 ) {} - KeyAlternate( sal_uInt16 nKey, sal_Unicode nChar = 0 ) : nKeyCode( nKey ), nCharCode( nChar ) {} -}; - -static KeyAlternate -GetAlternateKeyCode( const sal_uInt16 nKeyCode ) -{ - KeyAlternate aAlternate; - - switch( nKeyCode ) - { - case KEY_F10: aAlternate = KeyAlternate( KEY_MENU );break; - case KEY_F24: aAlternate = KeyAlternate( KEY_SUBTRACT, '-' );break; - } - - return aAlternate; -} - -bool GtkSalFrame::doKeyCallback( guint state, - guint keyval, - guint16 hardware_keycode, - guint8 group, - sal_Unicode aOrigCode, - bool bDown, - bool bSendRelease - ) -{ - SalKeyEvent aEvent; - - aEvent.mnCharCode = aOrigCode; - aEvent.mnRepeat = 0; - - vcl::DeletionListener aDel( this ); - - /* - * #i42122# translate all keys with Ctrl and/or Alt to group 0 else - * shortcuts (e.g. Ctrl-o) will not work but be inserted by the - * application - * - * #i52338# do this for all keys that the independent part has no key code - * for - * - * fdo#41169 rather than use group 0, detect if there is a group which can - * be used to input Latin text and use that if possible - */ - aEvent.mnCode = GetKeyCode( keyval ); - if( aEvent.mnCode == 0 ) - { - gint best_group = SAL_MAX_INT32; - - // Try and find Latin layout - GdkKeymap* keymap = gdk_keymap_get_default(); - GdkKeymapKey *keys; - gint n_keys; - if (gdk_keymap_get_entries_for_keyval(keymap, GDK_KEY_A, &keys, &n_keys)) - { - // Find the lowest group that supports Latin layout - for (gint i = 0; i < n_keys; ++i) - { - if (keys[i].level != 0 && keys[i].level != 1) - continue; - best_group = std::min(best_group, keys[i].group); - if (best_group == 0) - break; - } - g_free(keys); - } - - //Unavailable, go with original group then I suppose - if (best_group == SAL_MAX_INT32) - best_group = group; - - guint updated_keyval = GetKeyValFor(keymap, hardware_keycode, best_group); - aEvent.mnCode = GetKeyCode(updated_keyval); - } - - aEvent.mnCode |= GetKeyModCode( state ); - - if( bDown ) - { - bool bHandled = CallCallback( SalEvent::KeyInput, &aEvent ); - // #i46889# copy AlternateKeyCode handling from generic plugin - if( ! bHandled ) - { - KeyAlternate aAlternate = GetAlternateKeyCode( aEvent.mnCode ); - if( aAlternate.nKeyCode ) - { - aEvent.mnCode = aAlternate.nKeyCode; - if( aAlternate.nCharCode ) - aEvent.mnCharCode = aAlternate.nCharCode; - CallCallback( SalEvent::KeyInput, &aEvent ); - } - } - if( bSendRelease && ! aDel.isDeleted() ) - { - CallCallback( SalEvent::KeyUp, &aEvent ); - } - } - else - CallCallback( SalEvent::KeyUp, &aEvent ); - - return false; -} - -GtkSalFrame::GtkSalFrame( SalFrame* pParent, SalFrameStyleFlags nStyle ) - : m_nXScreen( getDisplay()->GetDefaultXScreen() ) - , m_bGraphics(false) -{ - getDisplay()->registerFrame( this ); - m_bDefaultPos = true; - m_bDefaultSize = ( (nStyle & SalFrameStyleFlags::SIZEABLE) && ! pParent ); - m_bWindowIsGtkPlug = false; - Init( pParent, nStyle ); -} - -GtkSalFrame::GtkSalFrame( SystemParentData* pSysData ) - : m_nXScreen( getDisplay()->GetDefaultXScreen() ) - , m_bGraphics(false) -{ - getDisplay()->registerFrame( this ); - // permanently ignore errors from our unruly children ... - GetGenericUnixSalData()->ErrorTrapPush(); - m_bDefaultPos = true; - m_bDefaultSize = true; - Init( pSysData ); -} - -#ifdef ENABLE_GMENU_INTEGRATION - -static void -gdk_x11_window_set_utf8_property (GdkWindow *window, - const gchar *name, - const gchar *value) -{ - GdkDisplay* display = gdk_window_get_display (window); - - if (value != nullptr) - { - XChangeProperty (GDK_DISPLAY_XDISPLAY (display), - GDK_WINDOW_XID (window), - gdk_x11_get_xatom_by_name_for_display (display, name), - gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8, - PropModeReplace, reinterpret_cast<guchar const *>(value), strlen (value)); - } - else - { - XDeleteProperty (GDK_DISPLAY_XDISPLAY (display), - GDK_WINDOW_XID (window), - gdk_x11_get_xatom_by_name_for_display (display, name)); - } -} - -// AppMenu watch functions. - -static void ObjectDestroyedNotify( gpointer data ) -{ - if ( data ) { - g_object_unref( data ); - } -} - -static void hud_activated( gboolean hud_active, gpointer user_data ) -{ - if ( hud_active ) - { - SolarMutexGuard aGuard; - GtkSalFrame* pSalFrame = static_cast< GtkSalFrame* >( user_data ); - GtkSalMenu* pSalMenu = reinterpret_cast< GtkSalMenu* >( pSalFrame->GetMenu() ); - - if ( pSalMenu ) - pSalMenu->UpdateFull(); - } -} - -static gboolean ensure_dbus_setup( gpointer data ) -{ - GtkSalFrame* pSalFrame = static_cast< GtkSalFrame* >( data ); - GdkWindow* gdkWindow = widget_get_window( pSalFrame->getWindow() ); - - if ( gdkWindow != nullptr && g_object_get_data( G_OBJECT( gdkWindow ), "g-lo-menubar" ) == nullptr ) - { - // Get a DBus session connection. - if(!pSessionBus) - pSessionBus = g_bus_get_sync (G_BUS_TYPE_SESSION, nullptr, nullptr); - if( !pSessionBus ) - { - return FALSE; - } - - // Create menu model and action group attached to this frame. - GMenuModel* pMenuModel = G_MENU_MODEL( g_lo_menu_new() ); - GActionGroup* pActionGroup = reinterpret_cast<GActionGroup*>(g_lo_action_group_new()); - - // Generate menu paths. - ::Window windowId = GDK_WINDOW_XID( gdkWindow ); - gchar* aDBusWindowPath = g_strdup_printf( "/org/libreoffice/window/%lu", windowId ); - gchar* aDBusMenubarPath = g_strdup_printf( "/org/libreoffice/window/%lu/menus/menubar", windowId ); - - // Set window properties. - g_object_set_data_full( G_OBJECT( gdkWindow ), "g-lo-menubar", pMenuModel, ObjectDestroyedNotify ); - g_object_set_data_full( G_OBJECT( gdkWindow ), "g-lo-action-group", pActionGroup, ObjectDestroyedNotify ); - - gdk_x11_window_set_utf8_property( gdkWindow, "_GTK_APPLICATION_ID", "org.libreoffice" ); - gdk_x11_window_set_utf8_property( gdkWindow, "_GTK_UNIQUE_BUS_NAME", g_dbus_connection_get_unique_name( pSessionBus ) ); - gdk_x11_window_set_utf8_property( gdkWindow, "_GTK_APPLICATION_OBJECT_PATH", "/org/libreoffice" ); - gdk_x11_window_set_utf8_property( gdkWindow, "_GTK_WINDOW_OBJECT_PATH", aDBusWindowPath ); - gdk_x11_window_set_utf8_property( gdkWindow, "_GTK_MENUBAR_OBJECT_PATH", aDBusMenubarPath ); - - // Publish the menu model and the action group. - SAL_INFO("vcl.unity", "exporting menu model at " << pMenuModel << " for window " << windowId); - pSalFrame->m_nMenuExportId = g_dbus_connection_export_menu_model (pSessionBus, aDBusMenubarPath, pMenuModel, nullptr); - SAL_INFO("vcl.unity", "exporting action group at " << pActionGroup << " for window " << windowId); - pSalFrame->m_nActionGroupExportId = g_dbus_connection_export_action_group( pSessionBus, aDBusWindowPath, pActionGroup, nullptr); - pSalFrame->m_nHudAwarenessId = hud_awareness_register( pSessionBus, aDBusMenubarPath, hud_activated, pSalFrame, nullptr, nullptr ); - - g_free( aDBusWindowPath ); - g_free( aDBusMenubarPath ); - } - - return FALSE; -} - -void on_registrar_available( GDBusConnection * /*connection*/, - const gchar * /*name*/, - const gchar * /*name_owner*/, - gpointer user_data ) -{ - SolarMutexGuard aGuard; - - GtkSalFrame* pSalFrame = static_cast< GtkSalFrame* >( user_data ); - - SalMenu* pSalMenu = pSalFrame->GetMenu(); - - if ( pSalMenu != nullptr ) - { - GtkSalMenu* pGtkSalMenu = static_cast<GtkSalMenu*>(pSalMenu); - pGtkSalMenu->EnableUnity(true); - } -} - -// This is called when the registrar becomes unavailable. It shows the menubar. -void on_registrar_unavailable( GDBusConnection * /*connection*/, - const gchar * /*name*/, - gpointer user_data ) -{ - SolarMutexGuard aGuard; - - SAL_INFO("vcl.unity", "on_registrar_unavailable"); - - //pSessionBus = NULL; - GtkSalFrame* pSalFrame = static_cast< GtkSalFrame* >( user_data ); - - SalMenu* pSalMenu = pSalFrame->GetMenu(); - - if ( pSalMenu ) { - GtkSalMenu* pGtkSalMenu = static_cast< GtkSalMenu* >( pSalMenu ); - pGtkSalMenu->EnableUnity(false); - } -} -#endif - -void GtkSalFrame::EnsureAppMenuWatch() -{ -#ifdef ENABLE_GMENU_INTEGRATION - if ( !m_nWatcherId ) - { - // Get a DBus session connection. - if ( pSessionBus == nullptr ) - { - pSessionBus = g_bus_get_sync( G_BUS_TYPE_SESSION, nullptr, nullptr ); - - if ( pSessionBus == nullptr ) - return; - } - - // Publish the menu only if AppMenu registrar is available. - m_nWatcherId = g_bus_watch_name_on_connection( pSessionBus, - "com.canonical.AppMenu.Registrar", - G_BUS_NAME_WATCHER_FLAGS_NONE, - on_registrar_available, - on_registrar_unavailable, - this, - nullptr ); - } -#else - (void) this; // loplugin:staticmethods -#endif -} - -void GtkSalFrame::InvalidateGraphics() -{ - if( m_pGraphics ) - { - m_pGraphics->DeInit(); - m_pGraphics->SetWindow(nullptr); - m_pGraphics.reset(); - } -} - -GtkSalFrame::~GtkSalFrame() -{ - InvalidateGraphics(); - - if( m_pParent ) - m_pParent->m_aChildren.remove( this ); - - getDisplay()->deregisterFrame( this ); - - if( m_pRegion ) - { - gdk_region_destroy( m_pRegion ); - } - - m_pIMHandler.reset(); - - GtkWidget *pEventWidget = getMouseEventWidget(); - for (auto handler_id : m_aMouseSignalIds) - g_signal_handler_disconnect(G_OBJECT(pEventWidget), handler_id); - if( m_pFixedContainer ) - gtk_widget_destroy( GTK_WIDGET( m_pFixedContainer ) ); - if( m_pEventBox ) - gtk_widget_destroy( GTK_WIDGET(m_pEventBox) ); - { - SolarMutexGuard aGuard; -#if defined ENABLE_GMENU_INTEGRATION - if(m_nWatcherId) - g_bus_unwatch_name(m_nWatcherId); -#endif - if( m_pWindow ) - { - g_object_set_data( G_OBJECT( m_pWindow ), "SalFrame", nullptr ); - -#if defined ENABLE_GMENU_INTEGRATION - if ( pSessionBus ) - { - if ( m_nHudAwarenessId ) - hud_awareness_unregister( pSessionBus, m_nHudAwarenessId ); - if ( m_nMenuExportId ) - g_dbus_connection_unexport_menu_model( pSessionBus, m_nMenuExportId ); - if ( m_nActionGroupExportId ) - g_dbus_connection_unexport_action_group( pSessionBus, m_nActionGroupExportId ); - } -#endif - gtk_widget_destroy( m_pWindow ); - } - } - if( m_pForeignParent ) - g_object_unref( G_OBJECT( m_pForeignParent ) ); - if( m_pForeignTopLevel ) - g_object_unref( G_OBJECT( m_pForeignTopLevel) ); -} - -void GtkSalFrame::moveWindow( long nX, long nY ) -{ - if( isChild( false ) ) - { - if( m_pParent ) - gtk_fixed_move( m_pParent->getFixedContainer(), - m_pWindow, - nX - m_pParent->maGeometry.nX, nY - m_pParent->maGeometry.nY ); - } - else - gtk_window_move( GTK_WINDOW(m_pWindow), nX, nY ); -} - -void GtkSalFrame::widget_set_size_request(long nWidth, long nHeight) -{ - gtk_widget_set_size_request(m_pWindow, nWidth, nHeight ); -} - -void GtkSalFrame::window_resize(long nWidth, long nHeight) -{ - gtk_window_resize(GTK_WINDOW(m_pWindow), nWidth, nHeight); -} - -void GtkSalFrame::resizeWindow( long nWidth, long nHeight ) -{ - if( isChild( false ) ) - { - widget_set_size_request(nWidth, nHeight); - } - else if( ! isChild( true, false ) ) - window_resize(nWidth, nHeight); -} - -// tdf#124694 GtkFixed takes the max size of all its children as its -// preferred size, causing it to not clip its child, but grow instead. - -static void -ooo_fixed_size_request(GtkWidget*, GtkRequisition* req) -{ - req->width = 0; - req->height = 0; -} - -static void -ooo_fixed_class_init(GtkFixedClass *klass) -{ - GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass); - widget_class->size_request = ooo_fixed_size_request; -} - -/* - * Always use a sub-class of GtkFixed we can tag for a11y. This allows us to - * utilize GAIL for the toplevel window and toolkit implementation incl. - * key event listener support .. - */ - -GType -ooo_fixed_get_type() -{ - static GType type = 0; - - if (!type) { - static const GTypeInfo tinfo = - { - sizeof (GtkFixedClass), - nullptr, /* base init */ - nullptr, /* base finalize */ - reinterpret_cast<GClassInitFunc>(ooo_fixed_class_init), /* class init */ - nullptr, /* class finalize */ - nullptr, /* class data */ - sizeof (GtkFixed), /* instance size */ - 0, /* nb preallocs */ - nullptr, /* instance init */ - nullptr /* value table */ - }; - - type = g_type_register_static( GTK_TYPE_FIXED, "OOoFixed", - &tinfo, GTypeFlags(0)); - } - - return type; -} - -void GtkSalFrame::updateScreenNumber() -{ - int nScreen = 0; - GdkScreen *pScreen = gtk_widget_get_screen( m_pWindow ); - if( pScreen ) - nScreen = getDisplay()->getSystem()->getScreenMonitorIdx( pScreen, maGeometry.nX, maGeometry.nY ); - maGeometry.nDisplayScreenNumber = nScreen; -} - -GtkWidget *GtkSalFrame::getMouseEventWidget() const -{ - return m_pWindow; -} - -void GtkSalFrame::InitCommon() -{ - m_pEventBox = nullptr; - // add the fixed container child, - // fixed is needed since we have to position plugin windows - m_pFixedContainer = GTK_FIXED(g_object_new( ooo_fixed_get_type(), nullptr )); - gtk_container_add( GTK_CONTAINER(m_pWindow), GTK_WIDGET(m_pFixedContainer) ); - - GtkWidget *pEventWidget = getMouseEventWidget(); - - gtk_widget_set_app_paintable(GTK_WIDGET(m_pFixedContainer), true); - gtk_widget_set_double_buffered(GTK_WIDGET(m_pFixedContainer), false); - gtk_widget_set_redraw_on_allocate(GTK_WIDGET(m_pFixedContainer), false); - - - // connect signals - g_signal_connect( G_OBJECT(m_pWindow), "style-set", G_CALLBACK(signalStyleSet), this ); - m_aMouseSignalIds.push_back(g_signal_connect( G_OBJECT(pEventWidget), "button-press-event", G_CALLBACK(signalButton), this )); - m_aMouseSignalIds.push_back(g_signal_connect( G_OBJECT(pEventWidget), "motion-notify-event", G_CALLBACK(signalMotion), this )); - m_aMouseSignalIds.push_back(g_signal_connect( G_OBJECT(pEventWidget), "button-release-event", G_CALLBACK(signalButton), this )); - g_signal_connect( G_OBJECT(m_pFixedContainer), "expose-event", G_CALLBACK(signalExpose), this ); - g_signal_connect( G_OBJECT(m_pWindow), "focus-in-event", G_CALLBACK(signalFocus), this ); - g_signal_connect( G_OBJECT(m_pWindow), "focus-out-event", G_CALLBACK(signalFocus), this ); - g_signal_connect( G_OBJECT(m_pWindow), "map-event", G_CALLBACK(signalMap), this ); - g_signal_connect( G_OBJECT(m_pWindow), "unmap-event", G_CALLBACK(signalUnmap), this ); - g_signal_connect( G_OBJECT(m_pWindow), "configure-event", G_CALLBACK(signalConfigure), this ); - g_signal_connect( G_OBJECT(m_pWindow), "key-press-event", G_CALLBACK(signalKey), this ); - g_signal_connect( G_OBJECT(m_pWindow), "key-release-event", G_CALLBACK(signalKey), this ); - g_signal_connect( G_OBJECT(m_pWindow), "delete-event", G_CALLBACK(signalDelete), this ); - g_signal_connect( G_OBJECT(m_pWindow), "window-state-event", G_CALLBACK(signalWindowState), this ); - g_signal_connect( G_OBJECT(m_pWindow), "scroll-event", G_CALLBACK(signalScroll), this ); - g_signal_connect( G_OBJECT(m_pWindow), "leave-notify-event", G_CALLBACK(signalCrossing), this ); - g_signal_connect( G_OBJECT(m_pWindow), "enter-notify-event", G_CALLBACK(signalCrossing), this ); - g_signal_connect( G_OBJECT(m_pWindow), "visibility-notify-event", G_CALLBACK(signalVisibility), this ); - g_signal_connect( G_OBJECT(m_pWindow), "destroy", G_CALLBACK(signalDestroy), this ); - - // init members - m_pCurrentCursor = nullptr; - m_nKeyModifiers = ModKeyFlags::NONE; - m_bFullscreen = false; - m_bSpanMonitorsWhenFullscreen = false; - m_nState = GDK_WINDOW_STATE_WITHDRAWN; - m_pIMHandler = nullptr; - m_pRegion = nullptr; - m_ePointerStyle = static_cast<PointerStyle>(0xffff); - m_bSetFocusOnMap = false; - m_pSalMenu = nullptr; - m_nWatcherId = 0; - m_nMenuExportId = 0; - m_nActionGroupExportId = 0; - m_nHudAwarenessId = 0; - - gtk_widget_add_events( m_pWindow, - GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | - GDK_VISIBILITY_NOTIFY_MASK | GDK_SCROLL_MASK - ); - - // show the widgets - gtk_widget_show_all( GTK_WIDGET(m_pFixedContainer) ); - - // realize the window, we need an XWindow id - gtk_widget_realize( m_pWindow ); - - //system data - m_aSystemData.nSize = sizeof( SystemEnvData ); - GtkSalDisplay* pDisp = GetGtkSalData()->GetGtkDisplay(); - m_aSystemData.pDisplay = pDisp->GetDisplay(); - m_aSystemData.pVisual = pDisp->GetVisual( m_nXScreen ).GetVisual(); - m_aSystemData.aWindow = widget_get_xid(m_pWindow); - m_aSystemData.aShellWindow = m_aSystemData.aWindow; - m_aSystemData.pSalFrame = this; - m_aSystemData.pWidget = m_pWindow; - m_aSystemData.nScreen = m_nXScreen.getXScreen(); - m_aSystemData.pToolkit = "gtk2"; - m_aSystemData.pPlatformName = "xcb"; - - m_bGraphics = false; - m_pGraphics = nullptr; - - // fake an initial geometry, gets updated via configure event or SetPosSize - if( m_bDefaultPos || m_bDefaultSize ) - { - Size aDefSize = calcDefaultSize(); - maGeometry.nX = -1; - maGeometry.nY = -1; - maGeometry.nWidth = aDefSize.Width(); - maGeometry.nHeight = aDefSize.Height(); - if( m_pParent ) - { - // approximation - maGeometry.nTopDecoration = m_pParent->maGeometry.nTopDecoration; - maGeometry.nBottomDecoration = m_pParent->maGeometry.nBottomDecoration; - maGeometry.nLeftDecoration = m_pParent->maGeometry.nLeftDecoration; - maGeometry.nRightDecoration = m_pParent->maGeometry.nRightDecoration; - } - else - { - maGeometry.nTopDecoration = 0; - maGeometry.nBottomDecoration = 0; - maGeometry.nLeftDecoration = 0; - maGeometry.nRightDecoration = 0; - } - } - else - { - resizeWindow( maGeometry.nWidth, maGeometry.nHeight ); - moveWindow( maGeometry.nX, maGeometry.nY ); - } - updateScreenNumber(); - - SetIcon(SV_ICON_ID_OFFICE); - - m_nWorkArea = pDisp->getWMAdaptor()->getCurrentWorkArea(); - /* #i64117# gtk sets a nice background pixmap - * but we actually don't really want that, so save - * some time on the Xserver as well as prevent - * some paint issues - */ - XSetWindowBackgroundPixmap( getDisplay()->GetDisplay(), - widget_get_xid(m_pWindow), - None ); -} - -static void lcl_set_accept_focus( GtkWindow* pWindow ) -{ - if (GetGtkSalData()->GetGtkDisplay()->getWMAdaptor()->getWindowManagerName().startsWith("Metacity")) - { - /* Metacity considers a toolbar type window as should not - * have focus on mapping, yet it believes it should unfocus - * the parent window... So convince Metacity to not do so, - * by disabling the focus until the window is mapped. We - * will restore the focus later in the map signal. - */ - gtk_window_set_accept_focus( pWindow, false ); - - /* remove WM_TAKE_FOCUS protocol; this would usually be the - * right thing, but gtk handles it internally whereas we - * want to handle it ourselves (as to sometimes not get - * the focus) - */ - Display* pDisplay = GetGtkSalData()->GetGtkDisplay()->GetDisplay(); - ::Window aWindow = widget_get_xid(GTK_WIDGET(pWindow)); - Atom* pProtocols = nullptr; - int nProtocols = 0; - XGetWMProtocols( pDisplay, - aWindow, - &pProtocols, &nProtocols ); - if( pProtocols ) - { - bool bSet = false; - Atom nTakeFocus = XInternAtom( pDisplay, "WM_TAKE_FOCUS", True ); - if( nTakeFocus ) - { - for( int i = 0; i < nProtocols; i++ ) - { - if( pProtocols[i] == nTakeFocus ) - { - for( int n = i; n < nProtocols-1; n++ ) - pProtocols[n] = pProtocols[n+1]; - nProtocols--; - i--; - bSet = true; - } - } - } - if( bSet ) - XSetWMProtocols( pDisplay, aWindow, pProtocols, nProtocols ); - XFree( pProtocols ); - } - } - else - { - // Only needed for Compiz. The toolbar type hint seems to be enough for other WMs. - gtk_window_set_focus_on_map( pWindow, false ); - } -} - -GtkSalFrame *GtkSalFrame::getFromWindow( GtkWindow *pWindow ) -{ - return static_cast<GtkSalFrame *>(g_object_get_data( G_OBJECT( pWindow ), "SalFrame" )); -} - -void GtkSalFrame::Init( SalFrame* pParent, SalFrameStyleFlags nStyle ) -{ - if( nStyle & SalFrameStyleFlags::DEFAULT ) // ensure default style - { - nStyle |= SalFrameStyleFlags::MOVEABLE | SalFrameStyleFlags::SIZEABLE | SalFrameStyleFlags::CLOSEABLE; - nStyle &= ~SalFrameStyleFlags::FLOAT; - } - - m_pParent = static_cast<GtkSalFrame*>(pParent); - m_pForeignParent = nullptr; - m_aForeignParentWindow = None; - m_pForeignTopLevel = nullptr; - m_aForeignTopLevelWindow = None; - m_nStyle = nStyle; - - GtkWindowType eWinType = ( (nStyle & SalFrameStyleFlags::FLOAT) && - ! (nStyle & SalFrameStyleFlags::OWNERDRAWDECORATION) - ) - ? GTK_WINDOW_POPUP : GTK_WINDOW_TOPLEVEL; - - if( nStyle & SalFrameStyleFlags::SYSTEMCHILD ) - { - m_pWindow = gtk_event_box_new(); - if( m_pParent ) - { - // insert into container - gtk_fixed_put( m_pParent->getFixedContainer(), - m_pWindow, 0, 0 ); - - } - } - else - { - m_pWindow = gtk_widget_new( GTK_TYPE_WINDOW, "type", eWinType, - "visible", FALSE, nullptr ); - } - g_object_set_data( G_OBJECT( m_pWindow ), "SalFrame", this ); - g_object_set_data( G_OBJECT( m_pWindow ), "libo-version", const_cast<char *>(LIBO_VERSION_DOTTED)); - - // force wm class hint - if (!isChild()) - { - if (m_pParent) - m_sWMClass = m_pParent->m_sWMClass; - updateWMClass(); - } - - if( m_pParent && m_pParent->m_pWindow && ! isChild() ) - gtk_window_set_screen( GTK_WINDOW(m_pWindow), gtk_window_get_screen( GTK_WINDOW(m_pParent->m_pWindow) ) ); - - if (m_pParent) - { - if (!(m_pParent->m_nStyle & SalFrameStyleFlags::PLUG)) - gtk_window_set_transient_for( GTK_WINDOW(m_pWindow), GTK_WINDOW(m_pParent->m_pWindow) ); - m_pParent->m_aChildren.push_back( this ); - } - - InitCommon(); - - // set window type - bool bDecoHandling = - ! isChild() && - ( ! (nStyle & SalFrameStyleFlags::FLOAT) || - (nStyle & SalFrameStyleFlags::OWNERDRAWDECORATION) ); - - if( bDecoHandling ) - { - GdkWindowTypeHint eType = GDK_WINDOW_TYPE_HINT_NORMAL; - if( (nStyle & SalFrameStyleFlags::DIALOG) && m_pParent != nullptr ) - eType = GDK_WINDOW_TYPE_HINT_DIALOG; - if( nStyle & SalFrameStyleFlags::INTRO ) - { - gtk_window_set_role( GTK_WINDOW(m_pWindow), "splashscreen" ); - eType = GDK_WINDOW_TYPE_HINT_SPLASHSCREEN; - } - else if( nStyle & SalFrameStyleFlags::TOOLWINDOW ) - { - eType = GDK_WINDOW_TYPE_HINT_UTILITY; - gtk_window_set_skip_taskbar_hint( GTK_WINDOW(m_pWindow), true ); - } - else if( nStyle & SalFrameStyleFlags::OWNERDRAWDECORATION ) - { - eType = GDK_WINDOW_TYPE_HINT_TOOLBAR; - lcl_set_accept_focus( GTK_WINDOW(m_pWindow) ); - gtk_window_set_decorated( GTK_WINDOW(m_pWindow), false ); - } - if( (nStyle & SalFrameStyleFlags::PARTIAL_FULLSCREEN ) - && getDisplay()->getWMAdaptor()->isLegacyPartialFullscreen() ) - { - eType = GDK_WINDOW_TYPE_HINT_TOOLBAR; - gtk_window_set_keep_above( GTK_WINDOW(m_pWindow), true ); - } - gtk_window_set_type_hint( GTK_WINDOW(m_pWindow), eType ); - gtk_window_set_gravity( GTK_WINDOW(m_pWindow), GDK_GRAVITY_STATIC ); - gtk_window_set_resizable( GTK_WINDOW(m_pWindow), bool(nStyle & SalFrameStyleFlags::SIZEABLE) ); - } - else if( nStyle & SalFrameStyleFlags::FLOAT ) - gtk_window_set_type_hint( GTK_WINDOW(m_pWindow), GDK_WINDOW_TYPE_HINT_POPUP_MENU ); - -#ifdef ENABLE_GMENU_INTEGRATION - if( eWinType == GTK_WINDOW_TOPLEVEL ) - { - // Enable DBus native menu if available. - ensure_dbus_setup( this ); - } -#endif -} - -GdkNativeWindow GtkSalFrame::findTopLevelSystemWindow(GdkNativeWindow aWindow) -{ - ::Window aRoot, aParent; - ::Window* pChildren; - unsigned int nChildren; - bool bBreak = false; - do - { - pChildren = nullptr; - nChildren = 0; - aParent = aRoot = None; - XQueryTree( getDisplay()->GetDisplay(), aWindow, - &aRoot, &aParent, &pChildren, &nChildren ); - XFree( pChildren ); - if( aParent != aRoot ) - aWindow = aParent; - int nCount = 0; - Atom* pProps = XListProperties( getDisplay()->GetDisplay(), - aWindow, - &nCount ); - for( int i = 0; i < nCount && ! bBreak; ++i ) - bBreak = (pProps[i] == XA_WM_HINTS); - if( pProps ) - XFree( pProps ); - } while( aParent != aRoot && ! bBreak ); - - return aWindow; -} - -void GtkSalFrame::Init( SystemParentData* pSysData ) -{ - m_pParent = nullptr; - m_aForeignParentWindow = pSysData->aWindow; - m_pForeignParent = nullptr; - m_aForeignTopLevelWindow = findTopLevelSystemWindow(pSysData->aWindow); - m_pForeignTopLevel = gdk_window_foreign_new_for_display( getGdkDisplay(), m_aForeignTopLevelWindow ); - gdk_window_set_events( m_pForeignTopLevel, GDK_STRUCTURE_MASK ); - - if( pSysData->nSize > sizeof(pSysData->nSize)+sizeof(pSysData->aWindow) && pSysData->bXEmbedSupport ) - { - m_pWindow = gtk_plug_new( pSysData->aWindow ); - m_bWindowIsGtkPlug = true; - widget_set_can_default( m_pWindow, true ); - widget_set_can_focus( m_pWindow, true ); - gtk_widget_set_sensitive( m_pWindow, true ); - } - else - { - m_pWindow = gtk_window_new( GTK_WINDOW_POPUP ); - m_bWindowIsGtkPlug = false; - } - m_nStyle = SalFrameStyleFlags::PLUG; - InitCommon(); - - m_pForeignParent = gdk_window_foreign_new_for_display( getGdkDisplay(), m_aForeignParentWindow ); - gdk_window_set_events( m_pForeignParent, GDK_STRUCTURE_MASK ); - - int x_ret, y_ret; - unsigned int w, h, bw, d; - ::Window aRoot; - XGetGeometry( getDisplay()->GetDisplay(), pSysData->aWindow, - &aRoot, &x_ret, &y_ret, &w, &h, &bw, &d ); - maGeometry.nWidth = w; - maGeometry.nHeight = h; - window_resize(w, h); - gtk_window_move( GTK_WINDOW(m_pWindow), 0, 0 ); - if( ! m_bWindowIsGtkPlug ) - { - XReparentWindow( getDisplay()->GetDisplay(), - widget_get_xid(m_pWindow), - static_cast<::Window>(pSysData->aWindow), - 0, 0 ); - } -} - -void GtkSalFrame::askForXEmbedFocus( sal_Int32 i_nTimeCode ) -{ - XEvent aEvent; - - memset( &aEvent, 0, sizeof(aEvent) ); - aEvent.xclient.window = m_aForeignParentWindow; - aEvent.xclient.type = ClientMessage; - aEvent.xclient.message_type = getDisplay()->getWMAdaptor()->getAtom( vcl_sal::WMAdaptor::XEMBED ); - aEvent.xclient.format = 32; - aEvent.xclient.data.l[0] = i_nTimeCode ? i_nTimeCode : CurrentTime; - aEvent.xclient.data.l[1] = 3; // XEMBED_REQUEST_FOCUS - aEvent.xclient.data.l[2] = 0; - aEvent.xclient.data.l[3] = 0; - aEvent.xclient.data.l[4] = 0; - - GetGenericUnixSalData()->ErrorTrapPush(); - XSendEvent( getDisplay()->GetDisplay(), - m_aForeignParentWindow, - False, NoEventMask, &aEvent ); - GetGenericUnixSalData()->ErrorTrapPop(); -} - -void GtkSalFrame::SetExtendedFrameStyle(SalExtStyle) -{ -} - -SalGraphics* GtkSalFrame::AcquireGraphics() -{ - if( m_bGraphics ) - return nullptr; - - if( !m_pGraphics ) - { - m_pGraphics.reset( new GtkSalGraphics( this, m_pWindow, m_nXScreen ) ); - } - m_bGraphics = true; - return m_pGraphics.get(); -} - -void GtkSalFrame::ReleaseGraphics( SalGraphics* pGraphics ) -{ - (void) pGraphics; - assert( pGraphics == m_pGraphics.get() ); - m_bGraphics = false; -} - -bool GtkSalFrame::PostEvent(std::unique_ptr<ImplSVEvent> pData) -{ - getDisplay()->SendInternalEvent( this, pData.release() ); - return true; -} - -void GtkSalFrame::SetTitle( const OUString& rTitle ) -{ - m_aTitle = rTitle; - if( m_pWindow && ! isChild() ) - gtk_window_set_title( GTK_WINDOW(m_pWindow), OUStringToOString( rTitle, RTL_TEXTENCODING_UTF8 ).getStr() ); -} - -void GtkSalFrame::SetIcon( sal_uInt16 nIcon ) -{ - if( (m_nStyle & (SalFrameStyleFlags::PLUG|SalFrameStyleFlags::SYSTEMCHILD|SalFrameStyleFlags::FLOAT|SalFrameStyleFlags::INTRO|SalFrameStyleFlags::OWNERDRAWDECORATION)) - || ! m_pWindow ) - return; - - gchar* appicon; - - if (nIcon == SV_ICON_ID_TEXT) - appicon = g_strdup ("libreoffice-writer"); - else if (nIcon == SV_ICON_ID_SPREADSHEET) - appicon = g_strdup ("libreoffice-calc"); - else if (nIcon == SV_ICON_ID_DRAWING) - appicon = g_strdup ("libreoffice-draw"); - else if (nIcon == SV_ICON_ID_PRESENTATION) - appicon = g_strdup ("libreoffice-impress"); - else if (nIcon == SV_ICON_ID_DATABASE) - appicon = g_strdup ("libreoffice-base"); - else if (nIcon == SV_ICON_ID_FORMULA) - appicon = g_strdup ("libreoffice-math"); - else - appicon = g_strdup ("libreoffice-startcenter"); - - gtk_window_set_icon_name (GTK_WINDOW (m_pWindow), appicon); -} - -void GtkSalFrame::SetMenu( SalMenu* pSalMenu ) -{ - m_pSalMenu = static_cast<GtkSalMenu*>(pSalMenu); -} - -SalMenu* GtkSalFrame::GetMenu() -{ - return m_pSalMenu; -} - -void GtkSalFrame::DrawMenuBar() -{ -} - -void GtkSalFrame::Center() -{ - long nX, nY; - - if( m_pParent ) - { - nX = (static_cast<long>(m_pParent->maGeometry.nWidth) - static_cast<long>(maGeometry.nWidth))/2; - nY = (static_cast<long>(m_pParent->maGeometry.nHeight) - static_cast<long>(maGeometry.nHeight))/2; - } - else - { - GdkScreen *pScreen = nullptr; - gint px, py; - GdkModifierType nMask; - gdk_display_get_pointer( getGdkDisplay(), &pScreen, &px, &py, &nMask ); - if( !pScreen ) - pScreen = gtk_widget_get_screen( m_pWindow ); - - gint nMonitor; - nMonitor = gdk_screen_get_monitor_at_point( pScreen, px, py ); - - GdkRectangle aMonitor; - gdk_screen_get_monitor_geometry( pScreen, nMonitor, &aMonitor ); - - nX = aMonitor.x + (aMonitor.width - static_cast<long>(maGeometry.nWidth))/2; - nY = aMonitor.y + (aMonitor.height - static_cast<long>(maGeometry.nHeight))/2; - } - SetPosSize( nX, nY, 0, 0, SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y ); -} - -Size GtkSalFrame::calcDefaultSize() -{ - return bestmaxFrameSizeForScreenSize(getDisplay()->GetScreenSize(GetDisplayScreen())); -} - -void GtkSalFrame::SetDefaultSize() -{ - Size aDefSize = calcDefaultSize(); - - SetPosSize( 0, 0, aDefSize.Width(), aDefSize.Height(), - SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT ); - - if( (m_nStyle & SalFrameStyleFlags::DEFAULT) && m_pWindow ) - gtk_window_maximize( GTK_WINDOW(m_pWindow) ); -} - -static void initClientId() -{ - static bool bOnce = false; - if (!bOnce) - { - bOnce = true; - const OString& rID = SessionManagerClient::getSessionID(); - if (!rID.isEmpty()) - gdk_set_sm_client_id(rID.getStr()); - } -} - -void GtkSalFrame::Show( bool bVisible, bool bNoActivate ) -{ - if( m_pWindow ) - { - if( m_pParent && (m_pParent->m_nStyle & SalFrameStyleFlags::PARTIAL_FULLSCREEN) - && getDisplay()->getWMAdaptor()->isLegacyPartialFullscreen() ) - gtk_window_set_keep_above( GTK_WINDOW(m_pWindow), bVisible ); - if( bVisible ) - { - initClientId(); - getDisplay()->startupNotificationCompleted(); - - if( m_bDefaultPos ) - Center(); - if( m_bDefaultSize ) - SetDefaultSize(); - setMinMaxSize(); - - // #i45160# switch to desktop where a dialog with parent will appear - if( m_pParent && m_pParent->m_nWorkArea != m_nWorkArea && IS_WIDGET_MAPPED(m_pParent->m_pWindow) ) - getDisplay()->getWMAdaptor()->switchToWorkArea( m_pParent->m_nWorkArea ); - - if( isFloatGrabWindow() && - m_pParent && - m_nFloats == 0 && - ! getDisplay()->GetCaptureFrame() ) - { - /* #i63086# - * outsmart Metacity's "focus:mouse" mode - * which insists on taking the focus from the document - * to the new float. Grab focus to parent frame BEFORE - * showing the float (cannot grab it to the float - * before show). - */ - m_pParent->grabPointer( true, true ); - } - - if( ! bNoActivate && (m_nStyle & SalFrameStyleFlags::TOOLWINDOW) ) - m_bSetFocusOnMap = true; - - gtk_widget_show( m_pWindow ); - - if( isFloatGrabWindow() ) - { - m_nFloats++; - if( ! getDisplay()->GetCaptureFrame() && m_nFloats == 1 ) - { - grabPointer(true, true); - GtkSalFrame *pKeyboardFrame = m_pParent ? m_pParent : this; - pKeyboardFrame->grabKeyboard(true); - } - // #i44068# reset parent's IM context - if( m_pParent ) - m_pParent->EndExtTextInput(EndExtTextInputFlags::NONE); - } - if( m_bWindowIsGtkPlug ) - askForXEmbedFocus( 0 ); - } - else - { - if( isFloatGrabWindow() ) - { - m_nFloats--; - if( ! getDisplay()->GetCaptureFrame() && m_nFloats == 0) - { - GtkSalFrame *pKeyboardFrame = m_pParent ? m_pParent : this; - pKeyboardFrame->grabKeyboard(false); - grabPointer(false); - } - } - gtk_widget_hide( m_pWindow ); - if( m_pIMHandler ) - m_pIMHandler->focusChanged( false ); - // flush here; there may be a very seldom race between - // the display connection used for clipboard and our connection - Flush(); - } - CallCallback( SalEvent::Resize, nullptr ); - TriggerPaintEvent(); - } -} - -void GtkSalFrame::setMinMaxSize() -{ - /* #i34504# metacity (and possibly others) do not treat - * _NET_WM_STATE_FULLSCREEN and max_width/height independently; - * whether they should is undefined. So don't set the max size hint - * for a full screen window. - */ - if( m_pWindow && ! isChild() ) - { - GdkGeometry aGeo; - int aHints = 0; - if( m_nStyle & SalFrameStyleFlags::SIZEABLE ) - { - if( m_aMinSize.Width() && m_aMinSize.Height() && ! m_bFullscreen ) - { - aGeo.min_width = m_aMinSize.Width(); - aGeo.min_height = m_aMinSize.Height(); - aHints |= GDK_HINT_MIN_SIZE; - } - if( m_aMaxSize.Width() && m_aMaxSize.Height() && ! m_bFullscreen ) - { - aGeo.max_width = m_aMaxSize.Width(); - aGeo.max_height = m_aMaxSize.Height(); - aHints |= GDK_HINT_MAX_SIZE; - } - } - else - { - if( ! m_bFullscreen ) - { - aGeo.min_width = maGeometry.nWidth; - aGeo.min_height = maGeometry.nHeight; - aHints |= GDK_HINT_MIN_SIZE; - - aGeo.max_width = maGeometry.nWidth; - aGeo.max_height = maGeometry.nHeight; - aHints |= GDK_HINT_MAX_SIZE; - } - } - if( m_bFullscreen && m_aMaxSize.Width() && m_aMaxSize.Height() ) - { - aGeo.max_width = m_aMaxSize.Width(); - aGeo.max_height = m_aMaxSize.Height(); - aHints |= GDK_HINT_MAX_SIZE; - } - if( aHints ) - { - gtk_window_set_geometry_hints( GTK_WINDOW(m_pWindow), - nullptr, - &aGeo, - GdkWindowHints( aHints ) ); - } - } -} - -void GtkSalFrame::SetMaxClientSize( long nWidth, long nHeight ) -{ - if( ! isChild() ) - { - m_aMaxSize = Size( nWidth, nHeight ); - // Show does a setMinMaxSize - if( IS_WIDGET_MAPPED( m_pWindow ) ) - setMinMaxSize(); - } -} -void GtkSalFrame::SetMinClientSize( long nWidth, long nHeight ) -{ - if( ! isChild() ) - { - m_aMinSize = Size( nWidth, nHeight ); - if( m_pWindow ) - { - widget_set_size_request(nWidth, nHeight ); - // Show does a setMinMaxSize - if( IS_WIDGET_MAPPED( m_pWindow ) ) - setMinMaxSize(); - } - } -} - -void GtkSalFrame::AllocateFrame() -{ -} - -void GtkSalFrame::SetPosSize( long nX, long nY, long nWidth, long nHeight, sal_uInt16 nFlags ) -{ - if( !m_pWindow || isChild( true, false ) ) - return; - - bool bSized = false, bMoved = false; - - if( (nFlags & ( SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT )) && - (nWidth > 0 && nHeight > 0 ) // sometimes stupid things happen - ) - { - m_bDefaultSize = false; - - if( static_cast<unsigned long>(nWidth) != maGeometry.nWidth || static_cast<unsigned long>(nHeight) != maGeometry.nHeight ) - bSized = true; - maGeometry.nWidth = nWidth; - maGeometry.nHeight = nHeight; - - if( isChild( false ) ) - widget_set_size_request(nWidth, nHeight); - else if( ! ( m_nState & GDK_WINDOW_STATE_MAXIMIZED ) ) - window_resize(nWidth, nHeight); - setMinMaxSize(); - } - else if( m_bDefaultSize ) - SetDefaultSize(); - - m_bDefaultSize = false; - - if( nFlags & ( SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y ) ) - { - if( m_pParent ) - { - if( AllSettings::GetLayoutRTL() ) - nX = m_pParent->maGeometry.nWidth-maGeometry.nWidth-1-nX; - nX += m_pParent->maGeometry.nX; - nY += m_pParent->maGeometry.nY; - } - - if( nX != maGeometry.nX || nY != maGeometry.nY ) - bMoved = true; - maGeometry.nX = nX; - maGeometry.nY = nY; - - m_bDefaultPos = false; - - moveWindow( maGeometry.nX, maGeometry.nY ); - - updateScreenNumber(); - } - else if( m_bDefaultPos ) - Center(); - - m_bDefaultPos = false; - - if( bSized ) - AllocateFrame(); - - if( bSized && ! bMoved ) - CallCallback( SalEvent::Resize, nullptr ); - else if( bMoved && ! bSized ) - CallCallback( SalEvent::Move, nullptr ); - else if( bMoved && bSized ) - CallCallback( SalEvent::MoveResize, nullptr ); - - if (bSized) - TriggerPaintEvent(); -} - -void GtkSalFrame::GetClientSize( long& rWidth, long& rHeight ) -{ - if( m_pWindow && !(m_nState & GDK_WINDOW_STATE_ICONIFIED) ) - { - rWidth = maGeometry.nWidth; - rHeight = maGeometry.nHeight; - } - else - rWidth = rHeight = 0; -} - -void GtkSalFrame::GetWorkArea( tools::Rectangle& rRect ) -{ - rRect = GetGtkSalData()->GetGtkDisplay()->getWMAdaptor()->getWorkArea( 0 ); -} - -SalFrame* GtkSalFrame::GetParent() const -{ - return m_pParent; -} - -void GtkSalFrame::SetWindowState( const SalFrameState* pState ) -{ - if( ! m_pWindow || ! pState || isChild( true, false ) ) - return; - - const WindowStateMask nMaxGeometryMask = - WindowStateMask::X | WindowStateMask::Y | - WindowStateMask::Width | WindowStateMask::Height | - WindowStateMask::MaximizedX | WindowStateMask::MaximizedY | - WindowStateMask::MaximizedWidth | WindowStateMask::MaximizedHeight; - - if( (pState->mnMask & WindowStateMask::State) && - ! ( m_nState & GDK_WINDOW_STATE_MAXIMIZED ) && - (pState->mnState & WindowStateState::Maximized) && - (pState->mnMask & nMaxGeometryMask) == nMaxGeometryMask ) - { - resizeWindow( pState->mnWidth, pState->mnHeight ); - moveWindow( pState->mnX, pState->mnY ); - m_bDefaultPos = m_bDefaultSize = false; - - maGeometry.nX = pState->mnMaximizedX; - maGeometry.nY = pState->mnMaximizedY; - maGeometry.nWidth = pState->mnMaximizedWidth; - maGeometry.nHeight = pState->mnMaximizedHeight; - updateScreenNumber(); - - m_nState = GdkWindowState( m_nState | GDK_WINDOW_STATE_MAXIMIZED ); - m_aRestorePosSize = tools::Rectangle( Point( pState->mnX, pState->mnY ), - Size( pState->mnWidth, pState->mnHeight ) ); - CallCallback( SalEvent::Resize, nullptr ); - } - else if( pState->mnMask & (WindowStateMask::X | WindowStateMask::Y | - WindowStateMask::Width | WindowStateMask::Height ) ) - { - sal_uInt16 nPosSizeFlags = 0; - long nX = pState->mnX - (m_pParent ? m_pParent->maGeometry.nX : 0); - long nY = pState->mnY - (m_pParent ? m_pParent->maGeometry.nY : 0); - if( pState->mnMask & WindowStateMask::X ) - nPosSizeFlags |= SAL_FRAME_POSSIZE_X; - else - nX = maGeometry.nX - (m_pParent ? m_pParent->maGeometry.nX : 0); - if( pState->mnMask & WindowStateMask::Y ) - nPosSizeFlags |= SAL_FRAME_POSSIZE_Y; - else - nY = maGeometry.nY - (m_pParent ? m_pParent->maGeometry.nY : 0); - if( pState->mnMask & WindowStateMask::Width ) - nPosSizeFlags |= SAL_FRAME_POSSIZE_WIDTH; - if( pState->mnMask & WindowStateMask::Height ) - nPosSizeFlags |= SAL_FRAME_POSSIZE_HEIGHT; - SetPosSize( nX, nY, pState->mnWidth, pState->mnHeight, nPosSizeFlags ); - } - if( pState->mnMask & WindowStateMask::State && ! isChild() ) - { - if( pState->mnState & WindowStateState::Maximized ) - gtk_window_maximize( GTK_WINDOW(m_pWindow) ); - else - gtk_window_unmaximize( GTK_WINDOW(m_pWindow) ); - /* #i42379# there is no rollup state in GDK; and rolled up windows are - * (probably depending on the WM) reported as iconified. If we iconify a - * window here that was e.g. a dialog, then it will be unmapped but still - * not be displayed in the task list, so it's an iconified window that - * the user cannot get out of this state. So do not set the iconified state - * on windows with a parent (that is transient frames) since these tend - * to not be represented in an icon task list. - */ - if( (pState->mnState & WindowStateState::Minimized) - && ! m_pParent ) - gtk_window_iconify( GTK_WINDOW(m_pWindow) ); - else - gtk_window_deiconify( GTK_WINDOW(m_pWindow) ); - } - TriggerPaintEvent(); -} - -bool GtkSalFrame::GetWindowState( SalFrameState* pState ) -{ - pState->mnState = WindowStateState::Normal; - pState->mnMask = WindowStateMask::State; - // rollup ? gtk 2.2 does not seem to support the shaded state - if( m_nState & GDK_WINDOW_STATE_ICONIFIED ) - pState->mnState |= WindowStateState::Minimized; - if( m_nState & GDK_WINDOW_STATE_MAXIMIZED ) - { - pState->mnState |= WindowStateState::Maximized; - pState->mnX = m_aRestorePosSize.Left(); - pState->mnY = m_aRestorePosSize.Top(); - pState->mnWidth = m_aRestorePosSize.GetWidth(); - pState->mnHeight = m_aRestorePosSize.GetHeight(); - pState->mnMaximizedX = maGeometry.nX; - pState->mnMaximizedY = maGeometry.nY; - pState->mnMaximizedWidth = maGeometry.nWidth; - pState->mnMaximizedHeight = maGeometry.nHeight; - pState->mnMask |= WindowStateMask::MaximizedX | - WindowStateMask::MaximizedY | - WindowStateMask::MaximizedWidth | - WindowStateMask::MaximizedHeight; - } - else - { - pState->mnX = maGeometry.nX; - pState->mnY = maGeometry.nY; - pState->mnWidth = maGeometry.nWidth; - pState->mnHeight = maGeometry.nHeight; - } - pState->mnMask |= WindowStateMask::X | - WindowStateMask::Y | - WindowStateMask::Width | - WindowStateMask::Height; - - return true; -} - -void GtkSalFrame::SetScreen( unsigned int nNewScreen, SetType eType, tools::Rectangle const *pSize ) -{ - if( !m_pWindow ) - return; - - if (maGeometry.nDisplayScreenNumber == nNewScreen && eType == SetType::RetainSize) - return; - - GdkScreen *pScreen = nullptr; - GdkRectangle aNewMonitor; - - bool bSpanAllScreens = nNewScreen == static_cast<unsigned int>(-1); - m_bSpanMonitorsWhenFullscreen = bSpanAllScreens && getDisplay()->getSystem()->GetDisplayScreenCount() > 1; - - if (m_bSpanMonitorsWhenFullscreen) //span all screens - { - pScreen = gtk_widget_get_screen( m_pWindow ); - aNewMonitor.x = 0; - aNewMonitor.y = 0; - aNewMonitor.width = gdk_screen_get_width(pScreen); - aNewMonitor.height = gdk_screen_get_height(pScreen); - } - else - { - gint nMonitor; - bool bSameMonitor = false; - - if (!bSpanAllScreens) - { - pScreen = getDisplay()->getSystem()->getScreenMonitorFromIdx( nNewScreen, nMonitor ); - if (!pScreen) - { - g_warning ("Attempt to move GtkSalFrame to invalid screen %d => " - "fallback to current\n", nNewScreen); - } - } - - if (!pScreen) - { - pScreen = gtk_widget_get_screen( m_pWindow ); - bSameMonitor = true; - } - - // Heavy lifting, need to move screen ... - if( pScreen != gtk_widget_get_screen( m_pWindow )) - gtk_window_set_screen( GTK_WINDOW( m_pWindow ), pScreen ); - - gint nOldMonitor = gdk_screen_get_monitor_at_window( - pScreen, widget_get_window( m_pWindow ) ); - if (bSameMonitor) - nMonitor = nOldMonitor; - - #if OSL_DEBUG_LEVEL > 1 - if( nMonitor == nOldMonitor ) - g_warning( "An apparently pointless SetScreen - should we elide it ?" ); - #endif - - GdkRectangle aOldMonitor; - gdk_screen_get_monitor_geometry( pScreen, nOldMonitor, &aOldMonitor ); - gdk_screen_get_monitor_geometry( pScreen, nMonitor, &aNewMonitor ); - - maGeometry.nX = aNewMonitor.x + maGeometry.nX - aOldMonitor.x; - maGeometry.nY = aNewMonitor.y + maGeometry.nY - aOldMonitor.y; - } - - bool bResize = false; - bool bVisible = IS_WIDGET_MAPPED( m_pWindow ); - if( bVisible ) - Show( false ); - - if( eType == SetType::Fullscreen ) - { - maGeometry.nX = aNewMonitor.x; - maGeometry.nY = aNewMonitor.y; - maGeometry.nWidth = aNewMonitor.width; - maGeometry.nHeight = aNewMonitor.height; - m_nStyle |= SalFrameStyleFlags::PARTIAL_FULLSCREEN; - bResize = true; - - // #i110881# for the benefit of compiz set a max size here - // else setting to fullscreen fails for unknown reasons - m_aMaxSize.setWidth( aNewMonitor.width ); - m_aMaxSize.setHeight( aNewMonitor.height ); - } - - if( pSize && eType == SetType::UnFullscreen ) - { - maGeometry.nX = pSize->Left(); - maGeometry.nY = pSize->Top(); - maGeometry.nWidth = pSize->GetWidth(); - maGeometry.nHeight = pSize->GetHeight(); - m_nStyle &= ~SalFrameStyleFlags::PARTIAL_FULLSCREEN; - bResize = true; - } - - if (bResize) - { - // temporarily re-sizeable - if( !(m_nStyle & SalFrameStyleFlags::SIZEABLE) ) - gtk_window_set_resizable( GTK_WINDOW(m_pWindow), TRUE ); - window_resize(maGeometry.nWidth, maGeometry.nHeight); - //I wonder if we should instead leave maGeometry alone and rely on - //configure-event to trigger signalConfigure and set it there - AllocateFrame(); - TriggerPaintEvent(); - } - - gtk_window_move( GTK_WINDOW( m_pWindow ), maGeometry.nX, maGeometry.nY ); - - // _NET_WM_STATE_FULLSCREEN (Metacity <-> KWin) - if( ! getDisplay()->getWMAdaptor()->isLegacyPartialFullscreen() ) - { - if( eType == SetType::Fullscreen ) - gtk_window_fullscreen( GTK_WINDOW( m_pWindow ) ); - else if( eType == SetType::UnFullscreen ) - gtk_window_unfullscreen( GTK_WINDOW( m_pWindow ) ); - } - - if( eType == SetType::UnFullscreen && - !(m_nStyle & SalFrameStyleFlags::SIZEABLE) ) - gtk_window_set_resizable( GTK_WINDOW( m_pWindow ), FALSE ); - - // FIXME: we should really let gtk+ handle our widget hierarchy ... - if( m_pParent && gtk_widget_get_screen( m_pParent->m_pWindow ) != pScreen ) - SetParent( nullptr ); - std::list< GtkSalFrame* > aChildren = m_aChildren; - for (auto const& child : aChildren) - child->SetScreen( nNewScreen, SetType::RetainSize ); - - m_bDefaultPos = m_bDefaultSize = false; - updateScreenNumber(); - CallCallback( SalEvent::MoveResize, nullptr ); - - if( bVisible ) - Show( true ); -} - -void GtkSalFrame::SetScreenNumber( unsigned int nNewScreen ) -{ - SetScreen( nNewScreen, SetType::RetainSize ); -} - -void GtkSalFrame::updateWMClass() -{ - OString aResClass = OUStringToOString(m_sWMClass, RTL_TEXTENCODING_ASCII_US); - const char *pResClass = !aResClass.isEmpty() ? aResClass.getStr() : - SalGenericSystem::getFrameClassName(); - Display *display; - - if (!getDisplay()->IsX11Display()) - return; - - display = getDisplay()->GetDisplay(); - - if( IS_WIDGET_REALIZED( m_pWindow ) ) - { - XClassHint* pClass = XAllocClassHint(); - OString aResName = SalGenericSystem::getFrameResName(); - pClass->res_name = const_cast<char*>(aResName.getStr()); - pClass->res_class = const_cast<char*>(pResClass); - XSetClassHint( display, - widget_get_xid(m_pWindow), - pClass ); - XFree( pClass ); - } -} - -void GtkSalFrame::SetApplicationID( const OUString &rWMClass ) -{ - if( rWMClass != m_sWMClass && ! isChild() ) - { - m_sWMClass = rWMClass; - updateWMClass(); - - for (auto const& child : m_aChildren) - child->SetApplicationID(rWMClass); - } -} - -void GtkSalFrame::ShowFullScreen( bool bFullScreen, sal_Int32 nScreen ) -{ - m_bFullscreen = bFullScreen; - - if( !m_pWindow || isChild() ) - return; - - if( bFullScreen ) - { - m_aRestorePosSize = tools::Rectangle( Point( maGeometry.nX, maGeometry.nY ), - Size( maGeometry.nWidth, maGeometry.nHeight ) ); - SetScreen( nScreen, SetType::Fullscreen ); - } - else - { - SetScreen( nScreen, SetType::UnFullscreen, - !m_aRestorePosSize.IsEmpty() ? &m_aRestorePosSize : nullptr ); - m_aRestorePosSize = tools::Rectangle(); - } -} - -void GtkSalFrame::StartPresentation( bool bStart ) -{ - boost::optional<guint> aWindow; - boost::optional<Display*> aDisplay; - if( getDisplay()->IsX11Display() ) - { - aWindow = widget_get_xid(m_pWindow); - aDisplay = GDK_DISPLAY_XDISPLAY( getGdkDisplay() ); - } - - m_ScreenSaverInhibitor.inhibit( bStart, - "presentation", - getDisplay()->IsX11Display(), - aWindow, - aDisplay ); -} - -void GtkSalFrame::SetAlwaysOnTop( bool bOnTop ) -{ - if( m_pWindow ) - gtk_window_set_keep_above( GTK_WINDOW( m_pWindow ), bOnTop ); -} - -void GtkSalFrame::ToTop( SalFrameToTop nFlags ) -{ - if( m_pWindow ) - { - if( isChild( false ) ) - gtk_widget_grab_focus( m_pWindow ); - else if( IS_WIDGET_MAPPED( m_pWindow ) ) - { - if( ! (nFlags & SalFrameToTop::GrabFocusOnly) ) - gtk_window_present( GTK_WINDOW(m_pWindow) ); - else - { - guint32 nUserTime = gdk_x11_get_server_time(GTK_WIDGET (m_pWindow)->window); - gdk_window_focus( widget_get_window(m_pWindow), nUserTime ); - } - } - else - { - if( nFlags & SalFrameToTop::RestoreWhenMin ) - gtk_window_present( GTK_WINDOW(m_pWindow) ); - } - } -} - -void GtkSalFrame::SetPointer( PointerStyle ePointerStyle ) -{ - if( m_pWindow && ePointerStyle != m_ePointerStyle ) - { - m_ePointerStyle = ePointerStyle; - GdkCursor *pCursor = getDisplay()->getCursor( ePointerStyle ); - gdk_window_set_cursor( widget_get_window(m_pWindow), pCursor ); - m_pCurrentCursor = pCursor; - - // #i80791# use grabPointer the same way as CaptureMouse, respective float grab - if( getDisplay()->MouseCaptured( this ) ) - grabPointer( true ); - else if( m_nFloats > 0 ) - grabPointer( true, true ); - } -} - -void GtkSalFrame::grabPointer( bool bGrab, bool bOwnerEvents ) -{ - static const char* pEnv = getenv( "SAL_NO_MOUSEGRABS" ); - if (pEnv && *pEnv) - return; - - if (!m_pWindow) - return; - - const int nMask = (GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK); - - if( bGrab ) - { - bool bUseGdkGrab = true; - for (auto pSalFrame : getDisplay()->getFrames() ) - { - const GtkSalFrame* pFrame = static_cast< const GtkSalFrame* >( pSalFrame ); - if( pFrame->m_bWindowIsGtkPlug ) - { - bUseGdkGrab = false; - break; - } - } - if( bUseGdkGrab ) - { - gdk_pointer_grab( widget_get_window( m_pWindow ), bOwnerEvents, - GdkEventMask(nMask), nullptr, m_pCurrentCursor, - GDK_CURRENT_TIME ); - } - else - { - // FIXME: for some unknown reason gdk_pointer_grab does not - // really produce owner events for GtkPlug windows - // the cause is yet unknown - - // this is of course a bad hack, especially as we cannot - // set the right cursor this way - XGrabPointer( getDisplay()->GetDisplay(), - widget_get_xid( m_pWindow ), - bOwnerEvents, - PointerMotionMask | ButtonPressMask | ButtonReleaseMask, - GrabModeAsync, - GrabModeAsync, - None, - None, - CurrentTime - ); - } - } - else - { - // Two GdkDisplays may be open - gdk_display_pointer_ungrab( getGdkDisplay(), GDK_CURRENT_TIME); - } -} - -void GtkSalFrame::grabKeyboard( bool bGrab ) -{ - static const char* pEnv = getenv("SAL_NO_MOUSEGRABS"); // let's not introduce a special var for this - if (pEnv && *pEnv) - return; - - if (!m_pWindow) - return; - - if( bGrab ) - { - gdk_keyboard_grab(widget_get_window(m_pWindow), true, - GDK_CURRENT_TIME); - } - else - { - gdk_keyboard_ungrab(GDK_CURRENT_TIME); - } -} - -void GtkSalFrame::CaptureMouse( bool bCapture ) -{ - getDisplay()->CaptureMouse( bCapture ? this : nullptr ); -} - -void GtkSalFrame::SetPointerPos( long nX, long nY ) -{ - GtkSalFrame* pFrame = this; - while( pFrame && pFrame->isChild( false ) ) - pFrame = pFrame->m_pParent; - if( ! pFrame ) - return; - - GdkScreen *pScreen = gtk_window_get_screen( GTK_WINDOW(pFrame->m_pWindow) ); - GdkDisplay *pDisplay = gdk_screen_get_display( pScreen ); - - /* when the application tries to center the mouse in the dialog the - * window isn't mapped already. So use coordinates relative to the root window. - */ - unsigned int nWindowLeft = maGeometry.nX + nX; - unsigned int nWindowTop = maGeometry.nY + nY; - - XWarpPointer( GDK_DISPLAY_XDISPLAY (pDisplay), None, - GDK_WINDOW_XID (gdk_screen_get_root_window( pScreen ) ), - 0, 0, 0, 0, nWindowLeft, nWindowTop); - // #i38648# ask for the next motion hint - gint x, y; - GdkModifierType mask; - gdk_window_get_pointer( widget_get_window(pFrame->m_pWindow) , &x, &y, &mask ); -} - -void GtkSalFrame::Flush() -{ - XFlush (GDK_DISPLAY_XDISPLAY (getGdkDisplay())); -} - -void GtkSalFrame::KeyCodeToGdkKey(const vcl::KeyCode& rKeyCode, - guint* pGdkKeyCode, GdkModifierType *pGdkModifiers) -{ - if ( pGdkKeyCode == nullptr || pGdkModifiers == nullptr ) - return; - - // Get GDK key modifiers - GdkModifierType nModifiers = GdkModifierType(0); - - if ( rKeyCode.IsShift() ) - nModifiers = static_cast<GdkModifierType>( nModifiers | GDK_SHIFT_MASK ); - - if ( rKeyCode.IsMod1() ) - nModifiers = static_cast<GdkModifierType>( nModifiers | GDK_CONTROL_MASK ); - - if ( rKeyCode.IsMod2() ) - nModifiers = static_cast<GdkModifierType>( nModifiers | GDK_MOD1_MASK ); - - *pGdkModifiers = nModifiers; - - // Get GDK keycode. - guint nKeyCode = 0; - - guint nCode = rKeyCode.GetCode(); - - if ( nCode >= KEY_0 && nCode <= KEY_9 ) - nKeyCode = ( nCode - KEY_0 ) + GDK_KEY_0; - else if ( nCode >= KEY_A && nCode <= KEY_Z ) - nKeyCode = ( nCode - KEY_A ) + GDK_KEY_A; - else if ( nCode >= KEY_F1 && nCode <= KEY_F26 ) - nKeyCode = ( nCode - KEY_F1 ) + GDK_KEY_F1; - else - { - switch (nCode) - { - case KEY_DOWN: nKeyCode = GDK_KEY_Down; break; - case KEY_UP: nKeyCode = GDK_KEY_Up; break; - case KEY_LEFT: nKeyCode = GDK_KEY_Left; break; - case KEY_RIGHT: nKeyCode = GDK_KEY_Right; break; - case KEY_HOME: nKeyCode = GDK_KEY_Home; break; - case KEY_END: nKeyCode = GDK_KEY_End; break; - case KEY_PAGEUP: nKeyCode = GDK_KEY_Page_Up; break; - case KEY_PAGEDOWN: nKeyCode = GDK_KEY_Page_Down; break; - case KEY_RETURN: nKeyCode = GDK_KEY_Return; break; - case KEY_ESCAPE: nKeyCode = GDK_KEY_Escape; break; - case KEY_TAB: nKeyCode = GDK_KEY_Tab; break; - case KEY_BACKSPACE: nKeyCode = GDK_KEY_BackSpace; break; - case KEY_SPACE: nKeyCode = GDK_KEY_space; break; - case KEY_INSERT: nKeyCode = GDK_KEY_Insert; break; - case KEY_DELETE: nKeyCode = GDK_KEY_Delete; break; - case KEY_ADD: nKeyCode = GDK_KEY_plus; break; - case KEY_SUBTRACT: nKeyCode = GDK_KEY_minus; break; - case KEY_MULTIPLY: nKeyCode = GDK_KEY_asterisk; break; - case KEY_DIVIDE: nKeyCode = GDK_KEY_slash; break; - case KEY_POINT: nKeyCode = GDK_KEY_period; break; - case KEY_COMMA: nKeyCode = GDK_KEY_comma; break; - case KEY_LESS: nKeyCode = GDK_KEY_less; break; - case KEY_GREATER: nKeyCode = GDK_KEY_greater; break; - case KEY_EQUAL: nKeyCode = GDK_KEY_equal; break; - case KEY_FIND: nKeyCode = GDK_KEY_Find; break; - case KEY_CONTEXTMENU: nKeyCode = GDK_KEY_Menu; break; - case KEY_HELP: nKeyCode = GDK_KEY_Help; break; - case KEY_UNDO: nKeyCode = GDK_KEY_Undo; break; - case KEY_REPEAT: nKeyCode = GDK_KEY_Redo; break; - case KEY_DECIMAL: nKeyCode = GDK_KEY_KP_Decimal; break; - case KEY_TILDE: nKeyCode = GDK_KEY_asciitilde; break; - case KEY_QUOTELEFT: nKeyCode = GDK_KEY_quoteleft; break; - case KEY_BRACKETLEFT: nKeyCode = GDK_KEY_bracketleft; break; - case KEY_BRACKETRIGHT: nKeyCode = GDK_KEY_bracketright; break; - case KEY_SEMICOLON: nKeyCode = GDK_KEY_semicolon; break; - case KEY_QUOTERIGHT: nKeyCode = GDK_KEY_quoteright; break; - - // Special cases - case KEY_COPY: nKeyCode = GDK_KEY_Copy; break; - case KEY_CUT: nKeyCode = GDK_KEY_Cut; break; - case KEY_PASTE: nKeyCode = GDK_KEY_Paste; break; - case KEY_OPEN: nKeyCode = GDK_KEY_Open; break; - } - } - - *pGdkKeyCode = nKeyCode; -} - -OUString GtkSalFrame::GetKeyName( sal_uInt16 nKeyCode ) -{ - return getDisplay()->GetKeyName( nKeyCode ); -} - -GdkDisplay *GtkSalFrame::getGdkDisplay() -{ - return GetGtkSalData()->GetGdkDisplay(); -} - -GtkSalDisplay *GtkSalFrame::getDisplay() -{ - return GetGtkSalData()->GetGtkDisplay(); -} - -SalFrame::SalPointerState GtkSalFrame::GetPointerState() -{ - SalPointerState aState; - GdkScreen* pScreen; - gint x, y; - GdkModifierType aMask; - gdk_display_get_pointer( getGdkDisplay(), &pScreen, &x, &y, &aMask ); - aState.maPos = Point( x - maGeometry.nX, y - maGeometry.nY ); - aState.mnState = GetMouseModCode( aMask ); - return aState; -} - -KeyIndicatorState GtkSalFrame::GetIndicatorState() -{ - return GetGtkSalData()->GetGtkDisplay()->GetIndicatorState(); -} - -void GtkSalFrame::SimulateKeyPress( sal_uInt16 nKeyCode ) -{ - GetGtkSalData()->GetGtkDisplay()->SimulateKeyPress(nKeyCode); -} - -void GtkSalFrame::SetInputContext( SalInputContext* pContext ) -{ - if( ! pContext ) - return; - - if( ! (pContext->mnOptions & InputContextFlags::Text) ) - return; - - // create a new im context - if( ! m_pIMHandler ) - m_pIMHandler.reset( new IMHandler( this ) ); -} - -void GtkSalFrame::EndExtTextInput( EndExtTextInputFlags nFlags ) -{ - if( m_pIMHandler ) - m_pIMHandler->endExtTextInput( nFlags ); -} - -bool GtkSalFrame::MapUnicodeToKeyCode( sal_Unicode , LanguageType , vcl::KeyCode& ) -{ - // not supported yet - return false; -} - -LanguageType GtkSalFrame::GetInputLanguage() -{ - return LANGUAGE_DONTKNOW; -} - -void GtkSalFrame::UpdateSettings( AllSettings& rSettings ) -{ - if( ! m_pWindow ) - return; - - GtkSalGraphics* pGraphics = m_pGraphics.get(); - bool bFreeGraphics = false; - if( ! pGraphics ) - { - pGraphics = static_cast<GtkSalGraphics*>(AcquireGraphics()); - if ( !pGraphics ) - { - SAL_WARN("vcl.gtk", "Could not get graphics - unable to update settings"); - return; - } - bFreeGraphics = true; - } - - pGraphics->UpdateSettings( rSettings ); - - if( bFreeGraphics ) - ReleaseGraphics( pGraphics ); -} - -void GtkSalFrame::Beep() -{ - gdk_display_beep( getGdkDisplay() ); -} - -const SystemEnvData* GtkSalFrame::GetSystemData() const -{ - return &m_aSystemData; -} - -void GtkSalFrame::SetParent( SalFrame* pNewParent ) -{ - if( m_pParent ) - m_pParent->m_aChildren.remove( this ); - m_pParent = static_cast<GtkSalFrame*>(pNewParent); - if( m_pParent ) - m_pParent->m_aChildren.push_back( this ); - if( ! isChild() ) - gtk_window_set_transient_for( GTK_WINDOW(m_pWindow), - (m_pParent && ! m_pParent->isChild(true,false)) ? GTK_WINDOW(m_pParent->m_pWindow) : nullptr - ); -} - -void GtkSalFrame::createNewWindow( ::Window aNewParent, bool bXEmbed, SalX11Screen nXScreen ) -{ - bool bWasVisible = m_pWindow && IS_WIDGET_MAPPED(m_pWindow); - if( bWasVisible ) - Show( false ); - - if( static_cast<int>(nXScreen.getXScreen()) >= getDisplay()->GetXScreenCount() ) - nXScreen = m_nXScreen; - - SystemParentData aParentData; - aParentData.nSize = sizeof(SystemParentData); - aParentData.aWindow = aNewParent; - aParentData.bXEmbedSupport = bXEmbed; - if( aNewParent == None ) - { - aParentData.aWindow = None; - aParentData.bXEmbedSupport = false; - } - else - { - // is new parent a root window ? - Display* pDisp = getDisplay()->GetDisplay(); - int nScreens = getDisplay()->GetXScreenCount(); - for( int i = 0; i < nScreens; i++ ) - { - if( aNewParent == RootWindow( pDisp, i ) ) - { - nXScreen = SalX11Screen( i ); - aParentData.aWindow = None; - aParentData.bXEmbedSupport = false; - break; - } - } - } - - // free xrender resources - if( m_pGraphics ) - m_pGraphics->SetDrawable( None, m_nXScreen ); - - // first deinit frame - m_pIMHandler.reset(); - if( m_pRegion ) - { - gdk_region_destroy( m_pRegion ); - } - - GtkWidget *pEventWidget = getMouseEventWidget(); - for (auto handler_id : m_aMouseSignalIds) - g_signal_handler_disconnect(G_OBJECT(pEventWidget), handler_id); - if( m_pFixedContainer ) - gtk_widget_destroy( GTK_WIDGET(m_pFixedContainer) ); - if( m_pEventBox ) - gtk_widget_destroy( GTK_WIDGET(m_pEventBox) ); - if( m_pWindow ) - gtk_widget_destroy( m_pWindow ); - if( m_pForeignParent ) - g_object_unref( G_OBJECT( m_pForeignParent ) ); - if( m_pForeignTopLevel ) - g_object_unref( G_OBJECT( m_pForeignTopLevel ) ); - - // init new window - m_bDefaultPos = m_bDefaultSize = false; - if( aParentData.aWindow != None ) - { - m_nStyle |= SalFrameStyleFlags::PLUG; - Init( &aParentData ); - } - else - { - m_nStyle &= ~SalFrameStyleFlags::PLUG; - Init( (m_pParent && m_pParent->m_nXScreen == m_nXScreen) ? m_pParent : nullptr, m_nStyle ); - } - - // update graphics - if( m_pGraphics ) - { - m_pGraphics->SetDrawable( widget_get_xid(m_pWindow), m_nXScreen ); - m_pGraphics->SetWindow( m_pWindow ); - } - - if( ! m_aTitle.isEmpty() ) - SetTitle( m_aTitle ); - - if( bWasVisible ) - Show( true ); - - std::list< GtkSalFrame* > aChildren; - aChildren.swap(m_aChildren); - for (auto const& child : aChildren) - child->createNewWindow( None, false, m_nXScreen ); - - // FIXME: SalObjects -} - -bool GtkSalFrame::SetPluginParent( SystemParentData* pSysParent ) -{ - GetGenericUnixSalData()->ErrorTrapPush(); // permanently ignore unruly children's errors - createNewWindow( pSysParent->aWindow, (pSysParent->nSize > sizeof(long)) && pSysParent->bXEmbedSupport, m_nXScreen ); - return true; -} - -void GtkSalFrame::ResetClipRegion() -{ - if( m_pWindow ) - gdk_window_shape_combine_region( widget_get_window( m_pWindow ), nullptr, 0, 0 ); -} - -void GtkSalFrame::BeginSetClipRegion( sal_uInt32 ) -{ - if( m_pRegion ) - gdk_region_destroy( m_pRegion ); - m_pRegion = gdk_region_new(); -} - -void GtkSalFrame::UnionClipRegion( long nX, long nY, long nWidth, long nHeight ) -{ - if( m_pRegion ) - { - GdkRectangle aRect; - aRect.x = nX; - aRect.y = nY; - aRect.width = nWidth; - aRect.height = nHeight; - gdk_region_union_with_rect( m_pRegion, &aRect ); - } -} - -void GtkSalFrame::EndSetClipRegion() -{ - if( m_pWindow && m_pRegion ) - gdk_window_shape_combine_region( widget_get_window(m_pWindow), m_pRegion, 0, 0 ); -} - -bool GtkSalFrame::Dispatch( const XEvent* pEvent ) -{ - bool bContinueDispatch = true; - - if( pEvent->type == PropertyNotify ) - { - vcl_sal::WMAdaptor* pAdaptor = getDisplay()->getWMAdaptor(); - Atom nDesktopAtom = pAdaptor->getAtom( vcl_sal::WMAdaptor::NET_WM_DESKTOP ); - if( pEvent->xproperty.atom == nDesktopAtom && - pEvent->xproperty.state == PropertyNewValue ) - { - m_nWorkArea = pAdaptor->getWindowWorkArea( widget_get_xid(m_pWindow) ); - } - } - else if( pEvent->type == ConfigureNotify ) - { - if( m_pForeignParent && pEvent->xconfigure.window == m_aForeignParentWindow ) - { - bContinueDispatch = false; - gtk_window_resize( GTK_WINDOW(m_pWindow), pEvent->xconfigure.width, pEvent->xconfigure.height ); - if( ( sal::static_int_cast< int >(maGeometry.nWidth) != - pEvent->xconfigure.width ) || - ( sal::static_int_cast< int >(maGeometry.nHeight) != - pEvent->xconfigure.height ) ) - { - maGeometry.nWidth = pEvent->xconfigure.width; - maGeometry.nHeight = pEvent->xconfigure.height; - setMinMaxSize(); - getDisplay()->SendInternalEvent( this, nullptr, SalEvent::Resize ); - } - } - else if( m_pForeignTopLevel && pEvent->xconfigure.window == m_aForeignTopLevelWindow ) - { - bContinueDispatch = false; - // update position - int x = 0, y = 0; - ::Window aChild; - XTranslateCoordinates( getDisplay()->GetDisplay(), - widget_get_xid(m_pWindow), - getDisplay()->GetRootWindow( getDisplay()->GetDefaultXScreen() ), - 0, 0, - &x, &y, - &aChild ); - if( x != maGeometry.nX || y != maGeometry.nY ) - { - maGeometry.nX = x; - maGeometry.nY = y; - getDisplay()->SendInternalEvent( this, nullptr, SalEvent::Move ); - } - } - } - else if( pEvent->type == ClientMessage && - pEvent->xclient.message_type == getDisplay()->getWMAdaptor()->getAtom( vcl_sal::WMAdaptor::XEMBED ) && - pEvent->xclient.window == widget_get_xid(m_pWindow) && - m_bWindowIsGtkPlug - ) - { - // FIXME: this should not be necessary, GtkPlug should do this - // transparently for us - if( pEvent->xclient.data.l[1] == 1 || // XEMBED_WINDOW_ACTIVATE - pEvent->xclient.data.l[1] == 2 // XEMBED_WINDOW_DEACTIVATE - ) - { - GdkEventFocus aEvent; - aEvent.type = GDK_FOCUS_CHANGE; - aEvent.window = widget_get_window( m_pWindow ); - aEvent.send_event = gint8(TRUE); - aEvent.in = gint16(pEvent->xclient.data.l[1] == 1); - signalFocus( m_pWindow, &aEvent, this ); - } - } - - return bContinueDispatch; -} - -gboolean GtkSalFrame::signalButton( GtkWidget*, GdkEventButton* pEvent, gpointer frame ) -{ - GtkSalFrame* pThis = static_cast<GtkSalFrame*>(frame); - - SalMouseEvent aEvent; - SalEvent nEventType = SalEvent::NONE; - switch( pEvent->type ) - { - case GDK_BUTTON_PRESS: - nEventType = SalEvent::MouseButtonDown; - break; - case GDK_BUTTON_RELEASE: - nEventType = SalEvent::MouseButtonUp; - break; - default: - return false; - } - switch( pEvent->button ) - { - case 1: aEvent.mnButton = MOUSE_LEFT; break; - case 2: aEvent.mnButton = MOUSE_MIDDLE; break; - case 3: aEvent.mnButton = MOUSE_RIGHT; break; - default: return false; - } - aEvent.mnTime = pEvent->time; - aEvent.mnX = static_cast<long>(pEvent->x_root) - pThis->maGeometry.nX; - aEvent.mnY = static_cast<long>(pEvent->y_root) - pThis->maGeometry.nY; - aEvent.mnCode = GetMouseModCode( pEvent->state ); - - bool bClosePopups = false; - if( pEvent->type == GDK_BUTTON_PRESS && - !(pThis->m_nStyle & SalFrameStyleFlags::OWNERDRAWDECORATION) - ) - { - if( m_nFloats > 0 ) - { - // close popups if user clicks outside our application - gint x, y; - bClosePopups = (gdk_display_get_window_at_pointer( GtkSalFrame::getGdkDisplay(), &x, &y ) == nullptr); - } - /* #i30306# release implicit pointer grab if no popups are open; else - * Drag cannot grab the pointer and will fail. - */ - if( m_nFloats < 1 || bClosePopups ) - gdk_display_pointer_ungrab( GtkSalFrame::getGdkDisplay(), GDK_CURRENT_TIME ); - } - - if( pThis->m_bWindowIsGtkPlug && - pEvent->type == GDK_BUTTON_PRESS && - pEvent->button == 1 ) - { - pThis->askForXEmbedFocus( pEvent->time ); - } - - if( AllSettings::GetLayoutRTL() ) - aEvent.mnX = pThis->maGeometry.nWidth-1-aEvent.mnX; - - vcl::DeletionListener aDel( pThis ); - - pThis->CallCallback( nEventType, &aEvent ); - - if( ! aDel.isDeleted() ) - { - if( bClosePopups ) - { - ImplSVData* pSVData = ImplGetSVData(); - if ( pSVData->maWinData.mpFirstFloat ) - { - if (!(pSVData->maWinData.mpFirstFloat->GetPopupModeFlags() & FloatWinPopupFlags::NoAppFocusClose)) - pSVData->maWinData.mpFirstFloat->EndPopupMode( FloatWinPopupEndFlags::Cancel | FloatWinPopupEndFlags::CloseAll ); - } - } - - if( ! aDel.isDeleted() ) - { - int frame_x = static_cast<int>(pEvent->x_root - pEvent->x); - int frame_y = static_cast<int>(pEvent->y_root - pEvent->y); - if( frame_x != pThis->maGeometry.nX || frame_y != pThis->maGeometry.nY ) - { - pThis->maGeometry.nX = frame_x; - pThis->maGeometry.nY = frame_y; - pThis->CallCallback( SalEvent::Move, nullptr ); - } - } - } - - return true; -} - -gboolean GtkSalFrame::signalScroll(GtkWidget*, GdkEvent* pInEvent, gpointer frame) -{ - GdkEventScroll& rEvent = pInEvent->scroll; - GtkSalFrame* pThis = static_cast<GtkSalFrame*>(frame); - - static sal_uLong nLines = 0; - if( ! nLines ) - { - char* pEnv = getenv( "SAL_WHEELLINES" ); - nLines = pEnv ? atoi( pEnv ) : 3; - if( nLines > 10 ) - nLines = SAL_WHEELMOUSE_EVENT_PAGESCROLL; - } - - bool bNeg = (rEvent.direction == GDK_SCROLL_DOWN || rEvent.direction == GDK_SCROLL_RIGHT ); - SalWheelMouseEvent aEvent; - aEvent.mnTime = rEvent.time; - aEvent.mnX = static_cast<sal_uLong>(rEvent.x); - aEvent.mnY = static_cast<sal_uLong>(rEvent.y); - aEvent.mnDelta = bNeg ? -120 : 120; - aEvent.mnNotchDelta = bNeg ? -1 : 1; - aEvent.mnScrollLines = nLines; - aEvent.mnCode = GetMouseModCode( rEvent.state ); - aEvent.mbHorz = (rEvent.direction == GDK_SCROLL_LEFT || rEvent.direction == GDK_SCROLL_RIGHT); - - if( AllSettings::GetLayoutRTL() ) - aEvent.mnX = pThis->maGeometry.nWidth-1-aEvent.mnX; - - pThis->CallCallback( SalEvent::WheelMouse, &aEvent ); - - return true; -} - -gboolean GtkSalFrame::signalMotion( GtkWidget*, GdkEventMotion* pEvent, gpointer frame ) -{ - GtkSalFrame* pThis = static_cast<GtkSalFrame*>(frame); - - SalMouseEvent aEvent; - aEvent.mnTime = pEvent->time; - aEvent.mnX = static_cast<long>(pEvent->x_root) - pThis->maGeometry.nX; - aEvent.mnY = static_cast<long>(pEvent->y_root) - pThis->maGeometry.nY; - aEvent.mnCode = GetMouseModCode( pEvent->state ); - aEvent.mnButton = 0; - - if( AllSettings::GetLayoutRTL() ) - aEvent.mnX = pThis->maGeometry.nWidth-1-aEvent.mnX; - - vcl::DeletionListener aDel( pThis ); - - pThis->CallCallback( SalEvent::MouseMove, &aEvent ); - - if( ! aDel.isDeleted() ) - { - int frame_x = static_cast<int>(pEvent->x_root - pEvent->x); - int frame_y = static_cast<int>(pEvent->y_root - pEvent->y); - if( frame_x != pThis->maGeometry.nX || frame_y != pThis->maGeometry.nY ) - { - pThis->maGeometry.nX = frame_x; - pThis->maGeometry.nY = frame_y; - pThis->CallCallback( SalEvent::Move, nullptr ); - } - - if( ! aDel.isDeleted() ) - { - // ask for the next hint - gint x, y; - GdkModifierType mask; - gdk_window_get_pointer( widget_get_window(GTK_WIDGET(pThis->m_pWindow)), &x, &y, &mask ); - } - } - - return true; -} - -gboolean GtkSalFrame::signalCrossing( GtkWidget*, GdkEventCrossing* pEvent, gpointer frame ) -{ - GtkSalFrame* pThis = static_cast<GtkSalFrame*>(frame); - SalMouseEvent aEvent; - aEvent.mnTime = pEvent->time; - aEvent.mnX = static_cast<long>(pEvent->x_root) - pThis->maGeometry.nX; - aEvent.mnY = static_cast<long>(pEvent->y_root) - pThis->maGeometry.nY; - aEvent.mnCode = GetMouseModCode( pEvent->state ); - aEvent.mnButton = 0; - - if (AllSettings::GetLayoutRTL()) - aEvent.mnX = pThis->maGeometry.nWidth-1-aEvent.mnX; - - pThis->CallCallback( (pEvent->type == GDK_ENTER_NOTIFY) ? SalEvent::MouseMove : SalEvent::MouseLeave, &aEvent ); - - return true; -} - -gboolean GtkSalFrame::signalExpose( GtkWidget*, GdkEventExpose* pEvent, gpointer frame ) -{ - GtkSalFrame* pThis = static_cast<GtkSalFrame*>(frame); - - struct SalPaintEvent aEvent( pEvent->area.x, pEvent->area.y, pEvent->area.width, pEvent->area.height, OpenGLHelper::isVCLOpenGLEnabled() ); - - pThis->CallCallback( SalEvent::Paint, &aEvent ); - - return false; -} - -gboolean GtkSalFrame::signalConfigure( GtkWidget*, GdkEventConfigure* pEvent, gpointer frame ) -{ - GtkSalFrame* pThis = static_cast<GtkSalFrame*>(frame); - - bool bMoved = false, bSized = false; - int x = pEvent->x, y = pEvent->y; - - /* HACK: during sizing/moving a toolbar pThis->maGeometry is actually - * already exact; even worse: due to the asynchronicity of configure - * events the borderwindow which would evaluate this event - * would size/move based on wrong data if we would actually evaluate - * this event. So let's swallow it. - */ - if( (pThis->m_nStyle & SalFrameStyleFlags::OWNERDRAWDECORATION) && - GtkSalFrame::getDisplay()->GetCaptureFrame() == pThis ) - return false; - - /* #i31785# claims we cannot trust the x,y members of the event; - * they are e.g. not set correctly on maximize/demaximize; - * yet the gdkdisplay-x11.c code handling configure_events has - * done this XTranslateCoordinates work since the day ~zero. - */ - if( x != pThis->maGeometry.nX || y != pThis->maGeometry.nY ) - { - bMoved = true; - pThis->maGeometry.nX = x; - pThis->maGeometry.nY = y; - } - /* #i86302# - * for non sizeable windows we set the min and max hint for the window manager to - * achieve correct sizing. However this is asynchronous and e.g. on Compiz - * it sometimes happens that the window gets resized to another size (some default) - * if we update the size here, subsequent setMinMaxSize will use this wrong size - * - which is not good since the window manager will now size the window back to this - * wrong size at some point. - */ - if( pThis->m_bFullscreen || (pThis->m_nStyle & (SalFrameStyleFlags::SIZEABLE | SalFrameStyleFlags::PLUG)) == SalFrameStyleFlags::SIZEABLE ) - { - if( pEvent->width != static_cast<int>(pThis->maGeometry.nWidth) || pEvent->height != static_cast<int>(pThis->maGeometry.nHeight) ) - { - bSized = true; - pThis->maGeometry.nWidth = pEvent->width; - pThis->maGeometry.nHeight = pEvent->height; - } - } - - // update decoration hints - if( ! (pThis->m_nStyle & SalFrameStyleFlags::PLUG) ) - { - GdkRectangle aRect; - gdk_window_get_frame_extents( widget_get_window(GTK_WIDGET(pThis->m_pWindow)), &aRect ); - pThis->maGeometry.nTopDecoration = y - aRect.y; - pThis->maGeometry.nBottomDecoration = aRect.y + aRect.height - y - pEvent->height; - pThis->maGeometry.nLeftDecoration = x - aRect.x; - pThis->maGeometry.nRightDecoration = aRect.x + aRect.width - x - pEvent->width; - } - else - { - pThis->maGeometry.nTopDecoration = - pThis->maGeometry.nBottomDecoration = - pThis->maGeometry.nLeftDecoration = - pThis->maGeometry.nRightDecoration = 0; - } - - pThis->updateScreenNumber(); - if( bSized ) - pThis->AllocateFrame(); - - if( bMoved && bSized ) - pThis->CallCallback( SalEvent::MoveResize, nullptr ); - else if( bMoved ) - pThis->CallCallback( SalEvent::Move, nullptr ); - else if( bSized ) - pThis->CallCallback( SalEvent::Resize, nullptr ); - - if (bSized) - pThis->TriggerPaintEvent(); - return false; -} - -void GtkSalFrame::TriggerPaintEvent() -{ -} - -gboolean GtkSalFrame::signalFocus( GtkWidget*, GdkEventFocus* pEvent, gpointer frame ) -{ - GtkSalFrame* pThis = static_cast<GtkSalFrame*>(frame); - - SalGenericInstance *pSalInstance = - static_cast< SalGenericInstance* >(GetSalData()->m_pInstance); - - // check if printers have changed (analogous to salframe focus handler) - pSalInstance->updatePrinterUpdate(); - - if( !pEvent->in ) - pThis->m_nKeyModifiers = ModKeyFlags::NONE; - - if( pThis->m_pIMHandler ) - pThis->m_pIMHandler->focusChanged( pEvent->in != 0 ); - - // ask for changed printers like generic implementation - if( pEvent->in && pSalInstance->isPrinterInit() ) - pSalInstance->updatePrinterUpdate(); - - // FIXME: find out who the hell steals the focus from our frame - // while we have the pointer grabbed, this should not come from - // the window manager. Is this an event that was still queued ? - // The focus does not seem to get set inside our process - - // in the meantime do not propagate focus get/lose if floats are open - if( m_nFloats == 0 ) - pThis->CallCallback( pEvent->in ? SalEvent::GetFocus : SalEvent::LoseFocus, nullptr ); - - return false; -} - -static OString getDisplayString() -{ - int nParams = rtl_getAppCommandArgCount(); - OUString aParam; - for( int i = 0; i < nParams; i++ ) - { - rtl_getAppCommandArg( i, &aParam.pData ); - if( i < nParams-1 && (aParam == "-display" || aParam == "--display" ) ) - { - rtl_getAppCommandArg( i+1, &aParam.pData ); - return OUStringToOString( aParam, osl_getThreadTextEncoding() ); - } - } - return OString(); -} - -gboolean GtkSalFrame::signalMap( GtkWidget *pWidget, GdkEvent*, gpointer frame ) -{ - GtkSalFrame* pThis = static_cast<GtkSalFrame*>(frame); - - //Spawn off a helper program that will attempt to set this fullscreen - //window either to span all displays or the current monitor - if (pThis->m_bFullscreen) - { - GdkWindow* gdkwin = widget_get_window(pThis->m_pWindow); - if (gdkwin) - { - OUString sProgramURL( "$BRAND_BASE_DIR/" LIBO_LIBEXEC_FOLDER "/xid-fullscreen-on-all-monitors"); - rtl::Bootstrap::expandMacros(sProgramURL); - OUString sProgram; - if (osl::FileBase::getSystemPathFromFileURL(sProgramURL, sProgram) == osl::File::E_None) - { - OString sFinalProgram(OUStringToOString(sProgram, osl_getThreadTextEncoding()) - + " " + OString::number(static_cast<int>(GDK_WINDOW_XID(gdkwin))) - + " " + OString::number(static_cast<int>(pThis->m_bSpanMonitorsWhenFullscreen))); - OString sDisplay(getDisplayString()); - if (!sDisplay.isEmpty()) - { - sFinalProgram += "--display " + sDisplay; - } - (void) system(sFinalProgram.getStr()); - } - } - } - - if ( pThis->m_nStyle & SalFrameStyleFlags::OWNERDRAWDECORATION ) - gtk_window_set_accept_focus( GTK_WINDOW(pWidget), true ); - - bool bSetFocus = pThis->m_bSetFocusOnMap; - pThis->m_bSetFocusOnMap = false; - - if( bSetFocus ) - pThis->ToTop( SalFrameToTop::GrabFocus ); - - pThis->CallCallback( SalEvent::Resize, nullptr ); - pThis->TriggerPaintEvent(); - - return false; -} - -gboolean GtkSalFrame::signalUnmap( GtkWidget*, GdkEvent*, gpointer frame ) -{ - GtkSalFrame* pThis = static_cast<GtkSalFrame*>(frame); - - pThis->CallCallback( SalEvent::Resize, nullptr ); - - return false; -} - -gboolean GtkSalFrame::signalKey( GtkWidget*, GdkEventKey* pEvent, gpointer frame ) -{ - GtkSalFrame* pThis = static_cast<GtkSalFrame*>(frame); - - vcl::DeletionListener aDel( pThis ); - - if( pThis->m_pIMHandler ) - { - if( pThis->m_pIMHandler->handleKeyEvent( pEvent ) ) - return true; - } - - // handle modifiers - if( pEvent->keyval == GDK_KEY_Shift_L || pEvent->keyval == GDK_KEY_Shift_R || - pEvent->keyval == GDK_KEY_Control_L || pEvent->keyval == GDK_KEY_Control_R || - pEvent->keyval == GDK_KEY_Alt_L || pEvent->keyval == GDK_KEY_Alt_R || - pEvent->keyval == GDK_KEY_Meta_L || pEvent->keyval == GDK_KEY_Meta_R || - pEvent->keyval == GDK_KEY_Super_L || pEvent->keyval == GDK_KEY_Super_R ) - { - sal_uInt16 nModCode = GetKeyModCode( pEvent->state ); - ModKeyFlags nExtModMask = ModKeyFlags::NONE; - sal_uInt16 nModMask = 0; - // pressing just the ctrl key leads to a keysym of XK_Control but - // the event state does not contain ControlMask. In the release - // event it's the other way round: it does contain the Control mask. - // The modifier mode therefore has to be adapted manually. - switch( pEvent->keyval ) - { - case GDK_KEY_Control_L: - nExtModMask = ModKeyFlags::LeftMod1; - nModMask = KEY_MOD1; - break; - case GDK_KEY_Control_R: - nExtModMask = ModKeyFlags::RightMod1; - nModMask = KEY_MOD1; - break; - case GDK_KEY_Alt_L: - nExtModMask = ModKeyFlags::LeftMod2; - nModMask = KEY_MOD2; - break; - case GDK_KEY_Alt_R: - nExtModMask = ModKeyFlags::RightMod2; - nModMask = KEY_MOD2; - break; - case GDK_KEY_Shift_L: - nExtModMask = ModKeyFlags::LeftShift; - nModMask = KEY_SHIFT; - break; - case GDK_KEY_Shift_R: - nExtModMask = ModKeyFlags::RightShift; - nModMask = KEY_SHIFT; - break; - // Map Meta/Super to MOD3 modifier on all Unix systems - // except macOS - case GDK_KEY_Meta_L: - case GDK_KEY_Super_L: - nExtModMask = ModKeyFlags::LeftMod3; - nModMask = KEY_MOD3; - break; - case GDK_KEY_Meta_R: - case GDK_KEY_Super_R: - nExtModMask = ModKeyFlags::RightMod3; - nModMask = KEY_MOD3; - break; - } - - SalKeyModEvent aModEvt; - aModEvt.mbDown = pEvent->type == GDK_KEY_PRESS; - aModEvt.mnCode = nModCode; - - if( pEvent->type == GDK_KEY_RELEASE ) - { - aModEvt.mnModKeyCode = pThis->m_nKeyModifiers; - nModCode &= ~nModMask; - pThis->m_nKeyModifiers &= ~nExtModMask; - } - else - { - nModCode |= nModMask; - pThis->m_nKeyModifiers |= nExtModMask; - aModEvt.mnModKeyCode = pThis->m_nKeyModifiers; - } - - pThis->CallCallback( SalEvent::KeyModChange, &aModEvt ); - } - else - { - pThis->doKeyCallback( pEvent->state, - pEvent->keyval, - pEvent->hardware_keycode, - pEvent->group, - sal_Unicode(gdk_keyval_to_unicode( pEvent->keyval )), - (pEvent->type == GDK_KEY_PRESS), - false ); - if( ! aDel.isDeleted() ) - pThis->m_nKeyModifiers = ModKeyFlags::NONE; - } - - if( !aDel.isDeleted() && pThis->m_pIMHandler ) - pThis->m_pIMHandler->updateIMSpotLocation(); - - return true; -} - -gboolean GtkSalFrame::signalDelete( GtkWidget*, GdkEvent*, gpointer frame ) -{ - GtkSalFrame* pThis = static_cast<GtkSalFrame*>(frame); - - pThis->CallCallback( SalEvent::Close, nullptr ); - - return true; -} - -void GtkSalFrame::signalStyleSet( GtkWidget*, GtkStyle* pPrevious, gpointer frame ) -{ - GtkSalFrame* pThis = static_cast<GtkSalFrame*>(frame); - - // every frame gets an initial style set on creation - // do not post these as the whole application tends to - // redraw itself to adjust to the new style - // where there IS no new style resulting in tremendous unnecessary flickering - if( pPrevious != nullptr ) - { - // signalStyleSet does NOT usually have the gdk lock - // so post user event to safely dispatch the SalEvent::SettingsChanged - // note: settings changed for multiple frames is avoided in winproc.cxx ImplHandleSettings - GtkSalFrame::getDisplay()->SendInternalEvent( pThis, nullptr, SalEvent::SettingsChanged ); - - // fire off font-changed when the system cairo font hints change - GtkInstance *pInstance = static_cast<GtkInstance*>(GetSalData()->m_pInstance); - const cairo_font_options_t* pLastCairoFontOptions = pInstance->GetLastSeenCairoFontOptions(); - const cairo_font_options_t* pCurrentCairoFontOptions = gdk_screen_get_font_options(gdk_screen_get_default()); - bool bFontSettingsChanged = true; - if (pLastCairoFontOptions && pCurrentCairoFontOptions) - bFontSettingsChanged = !cairo_font_options_equal(pLastCairoFontOptions, pCurrentCairoFontOptions); - else if (!pLastCairoFontOptions && !pCurrentCairoFontOptions) - bFontSettingsChanged = false; - if (bFontSettingsChanged) - { - pInstance->ResetLastSeenCairoFontOptions(pCurrentCairoFontOptions); - GtkSalFrame::getDisplay()->SendInternalEvent( pThis, nullptr, SalEvent::FontChanged ); - } - } - - /* #i64117# gtk sets a nice background pixmap - * but we actually don't really want that, so save - * some time on the Xserver as well as prevent - * some paint issues - */ - GdkWindow* pWin = widget_get_window(GTK_WIDGET(pThis->getWindow())); - if( pWin ) - { - ::Window aWin = GDK_WINDOW_XWINDOW(pWin); - if( aWin != None ) - XSetWindowBackgroundPixmap( GtkSalFrame::getDisplay()->GetDisplay(), - aWin, - None ); - } - if( ! pThis->m_pParent ) - { - // signalize theme changed for NWF caches - // FIXME: should be called only once for a style change - GtkSalGraphics::bThemeChanged = true; - } -} - -gboolean GtkSalFrame::signalWindowState( GtkWidget*, GdkEvent* pEvent, gpointer frame ) -{ - GtkSalFrame* pThis = static_cast<GtkSalFrame*>(frame); - if( (pThis->m_nState & GDK_WINDOW_STATE_ICONIFIED) != (pEvent->window_state.new_window_state & GDK_WINDOW_STATE_ICONIFIED ) ) - { - GtkSalFrame::getDisplay()->SendInternalEvent( pThis, nullptr, SalEvent::Resize ); - pThis->TriggerPaintEvent(); - } - - if( (pEvent->window_state.new_window_state & GDK_WINDOW_STATE_MAXIMIZED) && - ! (pThis->m_nState & GDK_WINDOW_STATE_MAXIMIZED) ) - { - pThis->m_aRestorePosSize = - tools::Rectangle( Point( pThis->maGeometry.nX, pThis->maGeometry.nY ), - Size( pThis->maGeometry.nWidth, pThis->maGeometry.nHeight ) ); - } - pThis->m_nState = pEvent->window_state.new_window_state; - - #if OSL_DEBUG_LEVEL > 1 - if( (pEvent->window_state.changed_mask & GDK_WINDOW_STATE_FULLSCREEN) ) - { - fprintf( stderr, "window %p %s full screen state\n", - pThis, - (pEvent->window_state.new_window_state & GDK_WINDOW_STATE_FULLSCREEN) ? "enters" : "leaves"); - } - #endif - - return false; -} - -gboolean GtkSalFrame::signalVisibility( GtkWidget*, GdkEventVisibility* /*pEvent*/, gpointer /*frame*/ ) -{ - return true; -} - -void GtkSalFrame::signalDestroy( GtkWidget* pObj, gpointer frame ) -{ - GtkSalFrame* pThis = static_cast<GtkSalFrame*>(frame); - if( pObj == pThis->m_pWindow ) - { - pThis->m_pFixedContainer = nullptr; - pThis->m_pEventBox = nullptr; - pThis->m_pWindow = nullptr; - pThis->InvalidateGraphics(); - } -} - -// GtkSalFrame::IMHandler - -GtkSalFrame::IMHandler::IMHandler( GtkSalFrame* pFrame ) -: m_pFrame(pFrame), - m_nPrevKeyPresses( 0 ), - m_pIMContext( nullptr ), - m_bFocused( true ), - m_bPreeditJustChanged( false ) -{ - m_aInputEvent.mpTextAttr = nullptr; - createIMContext(); -} - -GtkSalFrame::IMHandler::~IMHandler() -{ - // cancel an eventual event posted to begin preedit again - GtkSalFrame::getDisplay()->CancelInternalEvent( m_pFrame, &m_aInputEvent, SalEvent::ExtTextInput ); - deleteIMContext(); -} - -void GtkSalFrame::IMHandler::createIMContext() -{ - if( m_pIMContext ) - return; - - m_pIMContext = gtk_im_multicontext_new (); - g_signal_connect( m_pIMContext, "commit", - G_CALLBACK (signalIMCommit), this ); - g_signal_connect( m_pIMContext, "preedit_changed", - G_CALLBACK (signalIMPreeditChanged), this ); - g_signal_connect( m_pIMContext, "retrieve_surrounding", - G_CALLBACK (signalIMRetrieveSurrounding), this ); - g_signal_connect( m_pIMContext, "delete_surrounding", - G_CALLBACK (signalIMDeleteSurrounding), this ); - g_signal_connect( m_pIMContext, "preedit_start", - G_CALLBACK (signalIMPreeditStart), this ); - g_signal_connect( m_pIMContext, "preedit_end", - G_CALLBACK (signalIMPreeditEnd), this ); - - GetGenericUnixSalData()->ErrorTrapPush(); - gtk_im_context_set_client_window( m_pIMContext, widget_get_window(GTK_WIDGET(m_pFrame->m_pWindow)) ); - gtk_im_context_focus_in( m_pIMContext ); - GetGenericUnixSalData()->ErrorTrapPop(); - m_bFocused = true; - -} - -void GtkSalFrame::IMHandler::deleteIMContext() -{ - if( m_pIMContext ) - { - // first give IC a chance to deinitialize - GetGenericUnixSalData()->ErrorTrapPush(); - gtk_im_context_set_client_window( m_pIMContext, nullptr ); - GetGenericUnixSalData()->ErrorTrapPop(); - // destroy old IC - g_object_unref( m_pIMContext ); - m_pIMContext = nullptr; - } -} - -void GtkSalFrame::IMHandler::doCallEndExtTextInput() -{ - m_aInputEvent.mpTextAttr = nullptr; - m_pFrame->CallCallback( SalEvent::EndExtTextInput, nullptr ); -} - -void GtkSalFrame::IMHandler::updateIMSpotLocation() -{ - SalExtTextInputPosEvent aPosEvent; - m_pFrame->CallCallback( SalEvent::ExtTextInputPos, static_cast<void*>(&aPosEvent) ); - GdkRectangle aArea; - aArea.x = aPosEvent.mnX; - aArea.y = aPosEvent.mnY; - aArea.width = aPosEvent.mnWidth; - aArea.height = aPosEvent.mnHeight; - GetGenericUnixSalData()->ErrorTrapPush(); - gtk_im_context_set_cursor_location( m_pIMContext, &aArea ); - GetGenericUnixSalData()->ErrorTrapPop(); -} - -void GtkSalFrame::IMHandler::sendEmptyCommit() -{ - vcl::DeletionListener aDel( m_pFrame ); - - SalExtTextInputEvent aEmptyEv; - aEmptyEv.mpTextAttr = nullptr; - aEmptyEv.maText.clear(); - aEmptyEv.mnCursorPos = 0; - aEmptyEv.mnCursorFlags = 0; - m_pFrame->CallCallback( SalEvent::ExtTextInput, static_cast<void*>(&aEmptyEv) ); - if( ! aDel.isDeleted() ) - m_pFrame->CallCallback( SalEvent::EndExtTextInput, nullptr ); -} - -void GtkSalFrame::IMHandler::endExtTextInput( EndExtTextInputFlags /*nFlags*/ ) -{ - gtk_im_context_reset ( m_pIMContext ); - - if( m_aInputEvent.mpTextAttr ) - { - vcl::DeletionListener aDel( m_pFrame ); - // delete preedit in sal (commit an empty string) - sendEmptyCommit(); - if( ! aDel.isDeleted() ) - { - // mark previous preedit state again (will e.g. be sent at focus gain) - m_aInputEvent.mpTextAttr = m_aInputFlags.data(); - if( m_bFocused ) - { - // begin preedit again - GtkSalFrame::getDisplay()->SendInternalEvent( m_pFrame, &m_aInputEvent, SalEvent::ExtTextInput ); - } - } - } -} - -void GtkSalFrame::IMHandler::focusChanged( bool bFocusIn ) -{ - m_bFocused = bFocusIn; - if( bFocusIn ) - { - GetGenericUnixSalData()->ErrorTrapPush(); - gtk_im_context_focus_in( m_pIMContext ); - GetGenericUnixSalData()->ErrorTrapPop(); - if( m_aInputEvent.mpTextAttr ) - { - sendEmptyCommit(); - // begin preedit again - GtkSalFrame::getDisplay()->SendInternalEvent( m_pFrame, &m_aInputEvent, SalEvent::ExtTextInput ); - } - } - else - { - GetGenericUnixSalData()->ErrorTrapPush(); - gtk_im_context_focus_out( m_pIMContext ); - GetGenericUnixSalData()->ErrorTrapPop(); - // cancel an eventual event posted to begin preedit again - GtkSalFrame::getDisplay()->CancelInternalEvent( m_pFrame, &m_aInputEvent, SalEvent::ExtTextInput ); - } -} - -bool GtkSalFrame::IMHandler::handleKeyEvent( GdkEventKey* pEvent ) -{ - vcl::DeletionListener aDel( m_pFrame ); - - if( pEvent->type == GDK_KEY_PRESS ) - { - // Add this key press event to the list of previous key presses - // to which we compare key release events. If a later key release - // event has a matching key press event in this list, we swallow - // the key release because some GTK Input Methods don't swallow it - // for us. - m_aPrevKeyPresses.emplace_back(pEvent ); - m_nPrevKeyPresses++; - - // Also pop off the earliest key press event if there are more than 10 - // already. - while (m_nPrevKeyPresses > 10) - { - m_aPrevKeyPresses.pop_front(); - m_nPrevKeyPresses--; - } - - GObject* pRef = G_OBJECT( g_object_ref( G_OBJECT( m_pIMContext ) ) ); - - // #i51353# update spot location on every key input since we cannot - // know which key may activate a preedit choice window - updateIMSpotLocation(); - if( aDel.isDeleted() ) - return true; - - gboolean bResult = gtk_im_context_filter_keypress( m_pIMContext, pEvent ); - g_object_unref( pRef ); - - if( aDel.isDeleted() ) - return true; - - m_bPreeditJustChanged = false; - - if( bResult ) - return true; - else - { - SAL_WARN_IF( m_nPrevKeyPresses <= 0, "vcl.gtk", "key press has vanished !" ); - if( ! m_aPrevKeyPresses.empty() ) // sanity check - { - // event was not swallowed, do not filter a following - // key release event - // note: this relies on gtk_im_context_filter_keypress - // returning without calling a handler (in the "not swallowed" - // case ) which might change the previous key press list so - // we would pop the wrong event here - m_aPrevKeyPresses.pop_back(); - m_nPrevKeyPresses--; - } - } - } - - // Determine if we got an earlier key press event corresponding to this key release - if (pEvent->type == GDK_KEY_RELEASE) - { - GObject* pRef = G_OBJECT( g_object_ref( G_OBJECT( m_pIMContext ) ) ); - gboolean bResult = gtk_im_context_filter_keypress( m_pIMContext, pEvent ); - g_object_unref( pRef ); - - if( aDel.isDeleted() ) - return true; - - m_bPreeditJustChanged = false; - - auto iter = std::find(m_aPrevKeyPresses.begin(), m_aPrevKeyPresses.end(), pEvent); - // If we found a corresponding previous key press event, swallow the release - // and remove the earlier key press from our list - if (iter != m_aPrevKeyPresses.end()) - { - m_aPrevKeyPresses.erase(iter); - m_nPrevKeyPresses--; - return true; - } - - if( bResult ) - return true; - } - - return false; -} - -/* FIXME: -* #122282# still more hacking: some IMEs never start a preedit but simply commit -* in this case we cannot commit a single character. Workaround: do not do the -* single key hack for enter or space if the unicode committed does not match -*/ - -static bool checkSingleKeyCommitHack( guint keyval, sal_Unicode cCode ) -{ - bool bRet = true; - switch( keyval ) - { - case GDK_KEY_KP_Enter: - case GDK_KEY_Return: - if( cCode != '\n' && cCode != '\r' ) - bRet = false; - break; - case GDK_KEY_space: - case GDK_KEY_KP_Space: - if( cCode != ' ' ) - bRet = false; - break; - default: - break; - } - return bRet; -} - -void GtkSalFrame::IMHandler::signalIMCommit( GtkIMContext* pContext, gchar* pText, gpointer im_handler ) -{ - GtkSalFrame::IMHandler* pThis = static_cast<GtkSalFrame::IMHandler*>(im_handler); - - SolarMutexGuard aGuard; - vcl::DeletionListener aDel( pThis->m_pFrame ); - { - const bool bWasPreedit = - (pThis->m_aInputEvent.mpTextAttr != nullptr) || - pThis->m_bPreeditJustChanged; - - pThis->m_aInputEvent.mpTextAttr = nullptr; - pThis->m_aInputEvent.maText = OUString( pText, strlen(pText), RTL_TEXTENCODING_UTF8 ); - pThis->m_aInputEvent.mnCursorPos = pThis->m_aInputEvent.maText.getLength(); - pThis->m_aInputEvent.mnCursorFlags = 0; - - pThis->m_aInputFlags.clear(); - - /* necessary HACK: all keyboard input comes in here as soon as an IMContext is set - * which is logical and consequent. But since even simple input like - * <space> comes through the commit signal instead of signalKey - * and all kinds of windows only implement KeyInput (e.g. PushButtons, - * RadioButtons and a lot of other Controls), will send a single - * KeyInput/KeyUp sequence instead of an ExtText event if there - * never was a preedit and the text is only one character. - * - * In this case there the last ExtText event must have been - * SalEvent::EndExtTextInput, either because of a regular commit - * or because there never was a preedit. - */ - bool bSingleCommit = false; - if( ! bWasPreedit - && pThis->m_aInputEvent.maText.getLength() == 1 - && ! pThis->m_aPrevKeyPresses.empty() - ) - { - const PreviousKeyPress& rKP = pThis->m_aPrevKeyPresses.back(); - sal_Unicode aOrigCode = pThis->m_aInputEvent.maText[0]; - - if( checkSingleKeyCommitHack( rKP.keyval, aOrigCode ) ) - { - pThis->m_pFrame->doKeyCallback( rKP.state, rKP.keyval, rKP.hardware_keycode, rKP.group, aOrigCode, true, true ); - bSingleCommit = true; - } - } - if( ! bSingleCommit ) - { - pThis->m_pFrame->CallCallback( SalEvent::ExtTextInput, static_cast<void*>(&pThis->m_aInputEvent)); - if( ! aDel.isDeleted() ) - pThis->doCallEndExtTextInput(); - } - if( ! aDel.isDeleted() ) - { - // reset input event - pThis->m_aInputEvent.maText.clear(); - pThis->m_aInputEvent.mnCursorPos = 0; - pThis->updateIMSpotLocation(); - } - } -#ifdef __sun - // #i51356# workaround a solaris IIIMP bug - // in case of partial commits the preedit changed signal - // and commit signal come in wrong order - if( ! aDel.isDeleted() ) - signalIMPreeditChanged( pContext, im_handler ); -#else - (void) pContext; -#endif -} - -void GtkSalFrame::IMHandler::signalIMPreeditChanged( GtkIMContext*, gpointer im_handler ) -{ - GtkSalFrame::IMHandler* pThis = static_cast<GtkSalFrame::IMHandler*>(im_handler); - - char* pText = nullptr; - PangoAttrList* pAttrs = nullptr; - gint nCursorPos = 0; - - gtk_im_context_get_preedit_string( pThis->m_pIMContext, - &pText, - &pAttrs, - &nCursorPos ); - if( pText && ! *pText ) // empty string - { - // change from nothing to nothing -> do not start preedit - // e.g. this will activate input into a calc cell without - // user input - if( pThis->m_aInputEvent.maText.getLength() == 0 ) - { - g_free( pText ); - pango_attr_list_unref( pAttrs ); - return; - } - } - - pThis->m_bPreeditJustChanged = true; - - bool bEndPreedit = (!pText || !*pText) && pThis->m_aInputEvent.mpTextAttr != nullptr; - pThis->m_aInputEvent.maText = pText ? OUString( pText, strlen(pText), RTL_TEXTENCODING_UTF8 ) : OUString(); - pThis->m_aInputEvent.mnCursorPos = nCursorPos; - pThis->m_aInputEvent.mnCursorFlags = 0; - - pThis->m_aInputFlags = std::vector<ExtTextInputAttr>( std::max( 1, static_cast<int>(pThis->m_aInputEvent.maText.getLength()) ), ExtTextInputAttr::NONE ); - - PangoAttrIterator *iter = pango_attr_list_get_iterator(pAttrs); - do - { - GSList *attr_list = nullptr; - GSList *tmp_list = nullptr; - gint start, end; - ExtTextInputAttr sal_attr = ExtTextInputAttr::NONE; - - pango_attr_iterator_range (iter, &start, &end); - if (start == G_MAXINT || end == G_MAXINT) - { - auto len = pText ? g_utf8_strlen(pText, -1) : 0; - if (end == G_MAXINT) - end = len; - if (start == G_MAXINT) - start = len; - } - if (end == start) - continue; - - start = g_utf8_pointer_to_offset (pText, pText + start); - end = g_utf8_pointer_to_offset (pText, pText + end); - - tmp_list = attr_list = pango_attr_iterator_get_attrs (iter); - while (tmp_list) - { - PangoAttribute *pango_attr = static_cast<PangoAttribute *>(tmp_list->data); - - switch (pango_attr->klass->type) - { - case PANGO_ATTR_BACKGROUND: - sal_attr |= ExtTextInputAttr::Highlight; - pThis->m_aInputEvent.mnCursorFlags |= EXTTEXTINPUT_CURSOR_INVISIBLE; - break; - case PANGO_ATTR_UNDERLINE: - sal_attr |= ExtTextInputAttr::Underline; - break; - case PANGO_ATTR_STRIKETHROUGH: - sal_attr |= ExtTextInputAttr::RedText; - break; - default: - break; - } - pango_attribute_destroy (pango_attr); - tmp_list = tmp_list->next; - } - if (sal_attr == ExtTextInputAttr::NONE) - sal_attr |= ExtTextInputAttr::Underline; - g_slist_free (attr_list); - - // Set the sal attributes on our text - for (int i = start; i < end; ++i) - { - SAL_WARN_IF(i >= static_cast<int>(pThis->m_aInputFlags.size()), - "vcl.gtk", "pango attrib out of range. Broken range: " - << start << "," << end << " Legal range: 0," - << pThis->m_aInputFlags.size()); - if (i >= static_cast<int>(pThis->m_aInputFlags.size())) - continue; - pThis->m_aInputFlags[i] |= sal_attr; - } - } while (pango_attr_iterator_next (iter)); - pango_attr_iterator_destroy(iter); - - pThis->m_aInputEvent.mpTextAttr = pThis->m_aInputFlags.data(); - - g_free( pText ); - pango_attr_list_unref( pAttrs ); - - SolarMutexGuard aGuard; - vcl::DeletionListener aDel( pThis->m_pFrame ); - - pThis->m_pFrame->CallCallback( SalEvent::ExtTextInput, static_cast<void*>(&pThis->m_aInputEvent)); - if( bEndPreedit && ! aDel.isDeleted() ) - pThis->doCallEndExtTextInput(); - if( ! aDel.isDeleted() ) - pThis->updateIMSpotLocation(); -} - -void GtkSalFrame::IMHandler::signalIMPreeditStart( GtkIMContext*, gpointer /*im_handler*/ ) -{ -} - -void GtkSalFrame::IMHandler::signalIMPreeditEnd( GtkIMContext*, gpointer im_handler ) -{ - GtkSalFrame::IMHandler* pThis = static_cast<GtkSalFrame::IMHandler*>(im_handler); - - pThis->m_bPreeditJustChanged = true; - - SolarMutexGuard aGuard; - vcl::DeletionListener aDel( pThis->m_pFrame ); - pThis->doCallEndExtTextInput(); - if( ! aDel.isDeleted() ) - pThis->updateIMSpotLocation(); -} - -static uno::Reference<accessibility::XAccessibleEditableText> lcl_GetxText(vcl::Window *pFocusWin) -{ - uno::Reference<accessibility::XAccessibleEditableText> xText; - try - { - uno::Reference< accessibility::XAccessible > xAccessible( pFocusWin->GetAccessible() ); - if (xAccessible.is()) - xText = FindFocusedEditableText(xAccessible->getAccessibleContext()); - } - catch(const uno::Exception&) - { - TOOLS_WARN_EXCEPTION( "vcl.gtk", "Exception in getting input method surrounding text"); - } - return xText; -} - -gboolean GtkSalFrame::IMHandler::signalIMRetrieveSurrounding( GtkIMContext* pContext, gpointer /*im_handler*/ ) -{ - vcl::Window *pFocusWin = Application::GetFocusWindow(); - if (!pFocusWin) - return true; - - uno::Reference<accessibility::XAccessibleEditableText> xText = lcl_GetxText(pFocusWin); - if (xText.is()) - { - sal_Int32 nPosition = xText->getCaretPosition(); - OUString sAllText = xText->getText(); - OString sUTF = OUStringToOString(sAllText, RTL_TEXTENCODING_UTF8); - OUString sCursorText(sAllText.copy(0, nPosition)); - gtk_im_context_set_surrounding(pContext, sUTF.getStr(), sUTF.getLength(), - OUStringToOString(sCursorText, RTL_TEXTENCODING_UTF8).getLength()); - return true; - } - - return false; -} - -gboolean GtkSalFrame::IMHandler::signalIMDeleteSurrounding( GtkIMContext*, gint offset, gint nchars, - gpointer /*im_handler*/ ) -{ - vcl::Window *pFocusWin = Application::GetFocusWindow(); - if (!pFocusWin) - return true; - - uno::Reference<accessibility::XAccessibleEditableText> xText = lcl_GetxText(pFocusWin); - if (xText.is()) - { - sal_Int32 nPosition = xText->getCaretPosition(); - // #i111768# range checking - sal_Int32 nDeletePos = nPosition + offset; - sal_Int32 nDeleteEnd = nDeletePos + nchars; - if (nDeletePos < 0) - nDeletePos = 0; - if (nDeleteEnd < 0) - nDeleteEnd = 0; - if (nDeleteEnd > xText->getCharacterCount()) - nDeleteEnd = xText->getCharacterCount(); - - xText->deleteText(nDeletePos, nDeleteEnd); - //tdf91641 adjust cursor if deleted chars shift it forward (normal case) - if (nDeletePos < nPosition) - { - if (nDeleteEnd <= nPosition) - nPosition = nPosition - (nDeleteEnd - nDeletePos); - else - nPosition = nDeletePos; - - if (xText->getCharacterCount() >= nPosition) - xText->setCaretPosition( nPosition ); - } - return true; - } - - return false; -} - -Size GtkSalDisplay::GetScreenSize( int nDisplayScreen ) -{ - tools::Rectangle aRect = m_pSys->GetDisplayScreenPosSizePixel( nDisplayScreen ); - return Size( aRect.GetWidth(), aRect.GetHeight() ); -} - -sal_uIntPtr GtkSalFrame::GetNativeWindowHandle() -{ - return widget_get_xid(m_pWindow); -} - -GdkEvent* GtkSalFrame::makeFakeKeyPress(GtkWidget* pWidget) -{ - GdkEvent *event = gdk_event_new(GDK_KEY_PRESS); - event->key.window = GDK_WINDOW(g_object_ref(gtk_widget_get_window(pWidget))); - event->key.send_event = 1 /* TRUE */; - event->key.time = gtk_get_current_event_time(); - event->key.state = 0; - event->key.keyval = 0; - event->key.length = 0; - event->key.string = nullptr; - event->key.hardware_keycode = 0; - event->key.group = 0; - event->key.is_modifier = false; - return event; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/gtksalmenu.cxx b/vcl/unx/gtk/gtksalmenu.cxx deleted file mode 100644 index d0503519a084..000000000000 --- a/vcl/unx/gtk/gtksalmenu.cxx +++ /dev/null @@ -1,1444 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -#include <unx/gtk/gtksalmenu.hxx> - -#ifdef ENABLE_GMENU_INTEGRATION - -#include <unx/gendata.hxx> -#include <unx/saldisp.hxx> -#include <unx/gtk/gtkdata.hxx> -#include <unx/gtk/glomenu.h> -#include <unx/gtk/gloactiongroup.h> -#include <vcl/floatwin.hxx> -#include <vcl/menu.hxx> -#include <vcl/pngwrite.hxx> -#include <unx/gtk/gtkinst.hxx> - -#include <sal/log.hxx> -#include <tools/stream.hxx> -#include <window.h> -#include <strings.hrc> - -static bool bUnityMode = false; - -/* - * This function generates a unique command name for each menu item - */ -static gchar* GetCommandForItem(GtkSalMenu* pParentMenu, sal_uInt16 nItemId) -{ - OString aCommand("window-"); - aCommand = aCommand + OString::number(reinterpret_cast<unsigned long>(pParentMenu)); - aCommand = aCommand + "-" + OString::number(nItemId); - return g_strdup(aCommand.getStr()); -} - -static gchar* GetCommandForItem(GtkSalMenuItem* pSalMenuItem) -{ - return GetCommandForItem(pSalMenuItem->mpParentMenu, - pSalMenuItem->mnId); -} - -bool GtkSalMenu::PrepUpdate() -{ -#if GTK_CHECK_VERSION(3,0,0) - return mpMenuModel && mpActionGroup; -#else - return bUnityMode && mpMenuModel && mpActionGroup; -#endif -} - -/* - * Menu updating methods - */ - -static void RemoveSpareItemsFromNativeMenu( GLOMenu* pMenu, GList** pOldCommandList, unsigned nSection, unsigned nValidItems ) -{ - sal_Int32 nSectionItems = g_lo_menu_get_n_items_from_section( pMenu, nSection ); - - while ( nSectionItems > static_cast<sal_Int32>(nValidItems) ) - { - gchar* aCommand = g_lo_menu_get_command_from_item_in_section( pMenu, nSection, --nSectionItems ); - - if ( aCommand != nullptr && pOldCommandList != nullptr ) - *pOldCommandList = g_list_append( *pOldCommandList, g_strdup( aCommand ) ); - - g_free( aCommand ); - - g_lo_menu_remove_from_section( pMenu, nSection, nSectionItems ); - } -} - -typedef std::pair<GtkSalMenu*, sal_uInt16> MenuAndId; - -namespace -{ - MenuAndId decode_command(const gchar *action_name) - { - OString sCommand(action_name); - - sal_Int32 nIndex = 0; - OString sWindow = sCommand.getToken(0, '-', nIndex); - OString sGtkSalMenu = sCommand.getToken(0, '-', nIndex); - OString sItemId = sCommand.getToken(0, '-', nIndex); - - GtkSalMenu* pSalSubMenu = reinterpret_cast<GtkSalMenu*>(sGtkSalMenu.toInt64()); - - assert(sWindow == "window" && pSalSubMenu); - (void) sWindow; - - return MenuAndId(pSalSubMenu, sItemId.toInt32()); - } -} - -static void RemoveDisabledItemsFromNativeMenu(GLOMenu* pMenu, GList** pOldCommandList, - sal_Int32 nSection, GActionGroup* pActionGroup) -{ - while (nSection >= 0) - { - sal_Int32 nSectionItems = g_lo_menu_get_n_items_from_section( pMenu, nSection ); - while (nSectionItems--) - { - gchar* pCommand = g_lo_menu_get_command_from_item_in_section(pMenu, nSection, nSectionItems); - // remove disabled entries - bool bRemove = !g_action_group_get_action_enabled(pActionGroup, pCommand); - if (!bRemove) - { - //also remove any empty submenus - GLOMenu* pSubMenuModel = g_lo_menu_get_submenu_from_item_in_section(pMenu, nSection, nSectionItems); - if (pSubMenuModel) - { - gint nSubMenuSections = g_menu_model_get_n_items(G_MENU_MODEL(pSubMenuModel)); - if (nSubMenuSections == 0) - bRemove = true; - else if (nSubMenuSections == 1) - { - gint nItems = g_lo_menu_get_n_items_from_section(pSubMenuModel, 0); - if (nItems == 0) - bRemove = true; - else if (nItems == 1) - { - //If the only entry is the "No Selection Possible" entry, then we are allowed - //to removed it - gchar* pSubCommand = g_lo_menu_get_command_from_item_in_section(pSubMenuModel, 0, 0); - MenuAndId aMenuAndId(decode_command(pSubCommand)); - bRemove = aMenuAndId.second == 0xFFFF; - g_free(pSubCommand); - } - } - } - } - - if (bRemove) - { - //but tdf#86850 Always display clipboard functions - bRemove = g_strcmp0(pCommand, ".uno:Cut") && - g_strcmp0(pCommand, ".uno:Copy") && - g_strcmp0(pCommand, ".uno:Paste"); - } - - if (bRemove) - { - if (pCommand != nullptr && pOldCommandList != nullptr) - *pOldCommandList = g_list_append(*pOldCommandList, g_strdup(pCommand)); - g_lo_menu_remove_from_section(pMenu, nSection, nSectionItems); - } - - g_free(pCommand); - } - --nSection; - } -} - -static void RemoveSpareSectionsFromNativeMenu( GLOMenu* pMenu, GList** pOldCommandList, sal_Int32 nLastSection ) -{ - if ( pMenu == nullptr || pOldCommandList == nullptr ) - return; - - sal_Int32 n = g_menu_model_get_n_items( G_MENU_MODEL( pMenu ) ) - 1; - - for ( ; n > nLastSection; n--) - { - RemoveSpareItemsFromNativeMenu( pMenu, pOldCommandList, n, 0 ); - g_lo_menu_remove( pMenu, n ); - } -} - -static gint CompareStr( gpointer str1, gpointer str2 ) -{ - return g_strcmp0( static_cast<const gchar*>(str1), static_cast<const gchar*>(str2) ); -} - -static void RemoveUnusedCommands( GLOActionGroup* pActionGroup, GList* pOldCommandList, GList* pNewCommandList ) -{ - if ( pActionGroup == nullptr || pOldCommandList == nullptr ) - { - g_list_free_full( pOldCommandList, g_free ); - g_list_free_full( pNewCommandList, g_free ); - return; - } - - while ( pNewCommandList != nullptr ) - { - GList* pNewCommand = g_list_first( pNewCommandList ); - pNewCommandList = g_list_remove_link( pNewCommandList, pNewCommand ); - - gpointer aCommand = g_list_nth_data( pNewCommand, 0 ); - - GList* pOldCommand = g_list_find_custom( pOldCommandList, aCommand, reinterpret_cast<GCompareFunc>(CompareStr) ); - - if ( pOldCommand != nullptr ) - { - pOldCommandList = g_list_remove_link( pOldCommandList, pOldCommand ); - g_list_free_full( pOldCommand, g_free ); - } - - g_list_free_full( pNewCommand, g_free ); - } - - while ( pOldCommandList != nullptr ) - { - GList* pCommand = g_list_first( pOldCommandList ); - pOldCommandList = g_list_remove_link( pOldCommandList, pCommand ); - - gchar* aCommand = static_cast<gchar*>(g_list_nth_data( pCommand, 0 )); - - g_lo_action_group_remove( pActionGroup, aCommand ); - - g_list_free_full( pCommand, g_free ); - } -} - -void GtkSalMenu::ImplUpdate(bool bRecurse, bool bRemoveDisabledEntries) -{ - SolarMutexGuard aGuard; - - SAL_INFO("vcl.unity", "ImplUpdate pre PrepUpdate"); - if( !PrepUpdate() ) - return; - - if (mbNeedsUpdate) - { - mbNeedsUpdate = false; - if (mbMenuBar && maUpdateMenuBarIdle.IsActive()) - { - maUpdateMenuBarIdle.Stop(); - maUpdateMenuBarIdle.Invoke(); - return; - } - } - - Menu* pVCLMenu = mpVCLMenu; - GLOMenu* pLOMenu = G_LO_MENU( mpMenuModel ); - GLOActionGroup* pActionGroup = G_LO_ACTION_GROUP( mpActionGroup ); - SAL_INFO("vcl.unity", "Syncing vcl menu " << pVCLMenu << " to menu model " << pLOMenu << " and action group " << pActionGroup); - GList *pOldCommandList = nullptr; - GList *pNewCommandList = nullptr; - - sal_uInt16 nLOMenuSize = g_menu_model_get_n_items( G_MENU_MODEL( pLOMenu ) ); - - if ( nLOMenuSize == 0 ) - g_lo_menu_new_section( pLOMenu, 0, nullptr ); - - sal_Int32 nSection = 0; - sal_Int32 nItemPos = 0; - sal_Int32 validItems = 0; - sal_Int32 nItem; - - for ( nItem = 0; nItem < static_cast<sal_Int32>(GetItemCount()); nItem++ ) { - if ( !IsItemVisible( nItem ) ) - continue; - - GtkSalMenuItem *pSalMenuItem = GetItemAtPos( nItem ); - sal_uInt16 nId = pSalMenuItem->mnId; - - // PopupMenu::ImplExecute might add <No Selection Possible> entry to top-level - // popup menu, but we have our own implementation below, so skip that one. - if ( nId == 0xFFFF ) - continue; - - if ( pSalMenuItem->mnType == MenuItemType::SEPARATOR ) - { - // Delete extra items from current section. - RemoveSpareItemsFromNativeMenu( pLOMenu, &pOldCommandList, nSection, validItems ); - - nSection++; - nItemPos = 0; - validItems = 0; - - if ( nLOMenuSize <= nSection ) - { - g_lo_menu_new_section( pLOMenu, nSection, nullptr ); - nLOMenuSize++; - } - - continue; - } - - if ( nItemPos >= g_lo_menu_get_n_items_from_section( pLOMenu, nSection ) ) - g_lo_menu_insert_in_section( pLOMenu, nSection, nItemPos, "EMPTY STRING" ); - - // Get internal menu item values. - OUString aText = pVCLMenu->GetItemText( nId ); - Image aImage = pVCLMenu->GetItemImage( nId ); - bool bEnabled = pVCLMenu->IsItemEnabled( nId ); - vcl::KeyCode nAccelKey = pVCLMenu->GetAccelKey( nId ); - bool bChecked = pVCLMenu->IsItemChecked( nId ); - MenuItemBits itemBits = pVCLMenu->GetItemBits( nId ); - - // Store current item command in command list. - gchar *aCurrentCommand = g_lo_menu_get_command_from_item_in_section( pLOMenu, nSection, nItemPos ); - - if ( aCurrentCommand != nullptr ) - pOldCommandList = g_list_append( pOldCommandList, aCurrentCommand ); - - // Get the new command for the item. - gchar* aNativeCommand = GetCommandForItem(pSalMenuItem); - - // Force updating of native menu labels. - NativeSetItemText( nSection, nItemPos, aText ); - NativeSetItemIcon( nSection, nItemPos, aImage ); - NativeSetAccelerator( nSection, nItemPos, nAccelKey, nAccelKey.GetName( GetFrame()->GetWindow() ) ); - - if ( g_strcmp0( aNativeCommand, "" ) != 0 && pSalMenuItem->mpSubMenu == nullptr ) - { - NativeSetItemCommand( nSection, nItemPos, nId, aNativeCommand, itemBits, bChecked, false ); - NativeCheckItem( nSection, nItemPos, itemBits, bChecked ); - NativeSetEnableItem( aNativeCommand, bEnabled ); - - pNewCommandList = g_list_append( pNewCommandList, g_strdup( aNativeCommand ) ); - } - - GtkSalMenu* pSubmenu = pSalMenuItem->mpSubMenu; - - if ( pSubmenu && pSubmenu->GetMenu() ) - { - bool bNonMenuChangedToMenu = NativeSetItemCommand( nSection, nItemPos, nId, aNativeCommand, itemBits, false, true ); - pNewCommandList = g_list_append( pNewCommandList, g_strdup( aNativeCommand ) ); - - GLOMenu* pSubMenuModel = g_lo_menu_get_submenu_from_item_in_section( pLOMenu, nSection, nItemPos ); - - if ( pSubMenuModel == nullptr ) - { - g_lo_menu_new_submenu_in_item_in_section( pLOMenu, nSection, nItemPos ); - pSubMenuModel = g_lo_menu_get_submenu_from_item_in_section( pLOMenu, nSection, nItemPos ); - } - - g_object_unref( pSubMenuModel ); - - if (bRecurse || bNonMenuChangedToMenu) - { - SAL_INFO("vcl.unity", "preparing submenu " << pSubMenuModel << " to menu model " << G_MENU_MODEL(pSubMenuModel) << " and action group " << G_ACTION_GROUP(pActionGroup)); - pSubmenu->SetMenuModel( G_MENU_MODEL( pSubMenuModel ) ); - pSubmenu->SetActionGroup( G_ACTION_GROUP( pActionGroup ) ); - pSubmenu->ImplUpdate(true, bRemoveDisabledEntries); - } - } - - g_free( aNativeCommand ); - - ++nItemPos; - ++validItems; - } - - if (bRemoveDisabledEntries) - { - // Delete disabled items in last section. - RemoveDisabledItemsFromNativeMenu(pLOMenu, &pOldCommandList, nSection, G_ACTION_GROUP(pActionGroup)); - } - - // Delete extra items in last section. - RemoveSpareItemsFromNativeMenu( pLOMenu, &pOldCommandList, nSection, validItems ); - - // Delete extra sections. - RemoveSpareSectionsFromNativeMenu( pLOMenu, &pOldCommandList, nSection ); - - // Delete unused commands. - RemoveUnusedCommands( pActionGroup, pOldCommandList, pNewCommandList ); - - // Resolves: tdf#103166 if the menu is empty, add a disabled - // <No Selection Possible> placeholder. - sal_Int32 nSectionsCount = g_menu_model_get_n_items(G_MENU_MODEL(pLOMenu)); - gint nItemsCount = 0; - for (nSection = 0; nSection < nSectionsCount; ++nSection) - { - nItemsCount += g_lo_menu_get_n_items_from_section(pLOMenu, nSection); - if (nItemsCount) - break; - } - if (!nItemsCount) - { - gchar* aNativeCommand = GetCommandForItem(this, 0xFFFF); - OUString aPlaceholderText(VclResId(SV_RESID_STRING_NOSELECTIONPOSSIBLE)); - g_lo_menu_insert_in_section(pLOMenu, nSection-1, 0, - OUStringToOString(aPlaceholderText, RTL_TEXTENCODING_UTF8).getStr()); - NativeSetItemCommand(nSection-1, 0, 0xFFFF, aNativeCommand, MenuItemBits::NONE, false, false); - NativeSetEnableItem(aNativeCommand, false); - g_free(aNativeCommand); - } -} - -void GtkSalMenu::Update() -{ - //find out if top level is a menubar or not, if not, then it's a popup menu - //hierarchy and in those we hide (most) disabled entries - const GtkSalMenu* pMenu = this; - while (pMenu->mpParentSalMenu) - pMenu = pMenu->mpParentSalMenu; - ImplUpdate(false, !pMenu->mbMenuBar); -} - -#if GTK_CHECK_VERSION(3,0,0) -static void MenuPositionFunc(GtkMenu* menu, gint* x, gint* y, gboolean* push_in, gpointer user_data) -{ - Point *pPos = static_cast<Point*>(user_data); - *x = pPos->X(); - if (gtk_widget_get_default_direction() == GTK_TEXT_DIR_RTL) - { - GtkRequisition natural_size; - gtk_widget_get_preferred_size(GTK_WIDGET(menu), nullptr, &natural_size); - *x -= natural_size.width; - } - *y = pPos->Y(); - *push_in = false; -} -#endif - -bool GtkSalMenu::ShowNativePopupMenu(FloatingWindow* pWin, const tools::Rectangle& rRect, - FloatWinPopupFlags nFlags) -{ -#if GTK_CHECK_VERSION(3,0,0) - VclPtr<vcl::Window> xParent = pWin->ImplGetWindowImpl()->mpRealParent; - mpFrame = static_cast<GtkSalFrame*>(xParent->ImplGetFrame()); - - GLOActionGroup* pActionGroup = g_lo_action_group_new(); - mpActionGroup = G_ACTION_GROUP(pActionGroup); - mpMenuModel = G_MENU_MODEL(g_lo_menu_new()); - // Generate the main menu structure, populates mpMenuModel - UpdateFull(); - - GtkWidget *pWidget = gtk_menu_new_from_model(mpMenuModel); - gtk_menu_attach_to_widget(GTK_MENU(pWidget), mpFrame->getMouseEventWidget(), nullptr); - gtk_widget_insert_action_group(mpFrame->getMouseEventWidget(), "win", mpActionGroup); - - //run in a sub main loop because we need to keep vcl PopupMenu alive to use - //it during DispatchCommand, returning now to the outer loop causes the - //launching PopupMenu to be destroyed, instead run the subloop here - //until the gtk menu is destroyed - GMainLoop* pLoop = g_main_loop_new(nullptr, true); - g_signal_connect_swapped(G_OBJECT(pWidget), "deactivate", G_CALLBACK(g_main_loop_quit), pLoop); - -#if GTK_CHECK_VERSION(3,22,0) - if (gtk_check_version(3, 22, 0) == nullptr) - { - GdkGravity rect_anchor = GDK_GRAVITY_SOUTH_WEST, menu_anchor = GDK_GRAVITY_NORTH_WEST; - - if (nFlags & FloatWinPopupFlags::Left) - { - rect_anchor = GDK_GRAVITY_NORTH_WEST; - menu_anchor = GDK_GRAVITY_NORTH_EAST; - } - else if (nFlags & FloatWinPopupFlags::Up) - { - rect_anchor = GDK_GRAVITY_NORTH_WEST; - menu_anchor = GDK_GRAVITY_SOUTH_WEST; - } - else if (nFlags & FloatWinPopupFlags::Right) - { - rect_anchor = GDK_GRAVITY_NORTH_EAST; - } - - tools::Rectangle aFloatRect = FloatingWindow::ImplConvertToAbsPos(xParent, rRect); - aFloatRect.Move(-mpFrame->maGeometry.nX, -mpFrame->maGeometry.nY); - GdkRectangle rect {static_cast<int>(aFloatRect.Left()), static_cast<int>(aFloatRect.Top()), - static_cast<int>(aFloatRect.GetWidth()), static_cast<int>(aFloatRect.GetHeight())}; - - GdkWindow* gdkWindow = widget_get_window(mpFrame->getMouseEventWidget()); - gtk_menu_popup_at_rect(GTK_MENU(pWidget), gdkWindow, &rect, rect_anchor, menu_anchor, nullptr); - } - else -#endif - { - guint nButton; - guint32 nTime; - - //typically there is an event, and we can then distinguish if this was - //launched from the keyboard (gets auto-mnemoniced) or the mouse (which - //doesn't) - GdkEvent *pEvent = gtk_get_current_event(); - if (pEvent) - { - gdk_event_get_button(pEvent, &nButton); - nTime = gdk_event_get_time(pEvent); - } - else - { - nButton = 0; - nTime = GtkSalFrame::GetLastInputEventTime(); - } - - // do the same strange semantics as vcl popup windows to arrive at a frame geometry - // in mirrored UI case; best done by actually executing the same code - sal_uInt16 nArrangeIndex; - Point aPos = FloatingWindow::ImplCalcPos(pWin, rRect, nFlags, nArrangeIndex); - aPos = FloatingWindow::ImplConvertToAbsPos(xParent, aPos); - - gtk_menu_popup(GTK_MENU(pWidget), nullptr, nullptr, MenuPositionFunc, - &aPos, nButton, nTime); - } - - if (g_main_loop_is_running(pLoop)) - { - gdk_threads_leave(); - g_main_loop_run(pLoop); - gdk_threads_enter(); - } - g_main_loop_unref(pLoop); - - mpVCLMenu->Deactivate(); - - gtk_widget_insert_action_group(mpFrame->getMouseEventWidget(), "win", nullptr); - - gtk_widget_destroy(pWidget); - - g_object_unref(mpActionGroup); - ClearActionGroupAndMenuModel(); - - mpFrame = nullptr; - - return true; -#else - (void)pWin; - (void)rRect; - (void)nFlags; - return false; -#endif -} - -/* - * GtkSalMenu - */ - -GtkSalMenu::GtkSalMenu( bool bMenuBar ) : - mbInActivateCallback( false ), - mbMenuBar( bMenuBar ), - mbNeedsUpdate( false ), - mbReturnFocusToDocument( false ), - mbAddedGrab( false ), - mpMenuBarContainerWidget( nullptr ), - mpMenuAllowShrinkWidget( nullptr ), - mpMenuBarWidget( nullptr ), - mpMenuBarContainerProvider( nullptr ), - mpMenuBarProvider( nullptr ), - mpCloseButton( nullptr ), - mpVCLMenu( nullptr ), - mpParentSalMenu( nullptr |