From e2bab60de786a50dd46000a018b354196085b6a5 Mon Sep 17 00:00:00 2001 From: Matthieu Herrb Date: Mon, 11 Nov 2024 09:26:23 +0000 Subject: update to libXcursor 1.2.3 --- lib/libXcursor/ChangeLog | 207 +++++++++ lib/libXcursor/Makefile.bsd-wrapper | 4 +- lib/libXcursor/configure | 20 +- lib/libXcursor/configure.ac | 2 +- lib/libXcursor/include/X11/Xcursor/Xcursor.h.in | 7 + lib/libXcursor/m4/libtool.m4 | 51 ++- lib/libXcursor/man/Xcursor.man | 135 +++--- lib/libXcursor/src/cursor.c | 9 +- lib/libXcursor/src/display.c | 57 ++- lib/libXcursor/src/file.c | 575 +++++++++++++++++------- lib/libXcursor/src/library.c | 142 ++++-- lib/libXcursor/src/xcursorint.h | 47 ++ lib/libXcursor/src/xlib.c | 72 ++- 13 files changed, 1029 insertions(+), 299 deletions(-) diff --git a/lib/libXcursor/ChangeLog b/lib/libXcursor/ChangeLog index e894d1789..ab75a951a 100644 --- a/lib/libXcursor/ChangeLog +++ b/lib/libXcursor/ChangeLog @@ -1,3 +1,210 @@ +commit 8ae6cf61b18ecddf26f72a07bbfbd1ea9f022c36 +Author: Thomas E. Dickey +Date: Mon Nov 4 04:06:21 2024 -0500 + + amend per merge_requests/22#note_2642042 + + Signed-off-by: Thomas E. Dickey + +commit 68fe24020cf637df092db42c79b5e7ee0c04c17b +Author: Thomas E. Dickey +Date: Mon Nov 4 04:00:20 2024 -0500 + + amend per merge_requests/22#note_2642034 + + Signed-off-by: Thomas E. Dickey + +commit 8d27f282e40f855a41de53becba07fd5a2ceee0f +Author: Thomas E. Dickey +Date: Sun Nov 3 19:05:59 2024 -0500 + + reduce the message-check to ignore the over-long one + + Signed-off-by: Thomas E. Dickey + +commit d8b955d6b225f2dc2dcc7946fd73c87b5c9b4b2d +Author: Thomas E. Dickey +Date: Sun Nov 3 18:50:54 2024 -0500 + + fix overlooked compiler-warning + + Signed-off-by: Thomas E. Dickey + +commit cb2d1b97c39723efd2475fd6c93089aaca560e6a +Author: Thomas E. Dickey +Date: Sun Nov 3 18:33:06 2024 -0500 + + add debug-trace for the configuration information + + Signed-off-by: Thomas E. Dickey + +commit 304ac296f3207e46d36e0628af2702e83f6dc259 +Author: Thomas E. Dickey +Date: Sun Nov 3 17:36:03 2024 -0500 + + ensure ncomment and nimage values are positive + + Signed-off-by: Thomas E. Dickey + +commit 00a59a71994ce3e2484dc0241117d8d9a0095514 +Author: Thomas E. Dickey +Date: Fri Nov 1 19:49:27 2024 -0400 + + changes will suggest new release + + Signed-off-by: Thomas E. Dickey + +commit 83071fff3f09a3c2ff45061f6082d5d77d074073 +Author: Thomas E. Dickey +Date: Thu Oct 31 20:20:09 2024 -0400 + + document/tidy the new set/get functions + + Signed-off-by: Thomas E. Dickey + +commit fa5c5bb1bdf379e616e239e5edfac06d489d73ea +Author: Thomas E. Dickey +Date: Thu Oct 31 20:08:13 2024 -0400 + + document the new XCURSOR_RESIZED environment variable and resource "resized" + + Signed-off-by: Thomas E. Dickey + +commit f155414617de37ab49c81f8d9fa352dc31e77d80 +Author: Thomas E. Dickey +Date: Thu Oct 31 18:59:24 2024 -0400 + + add traces for library.c and xlib.c, also another internal function for dpy + + Signed-off-by: Thomas E. Dickey + +commit fbfe95e05f6791c1f66d5f16b200c19f243454b6 +Author: Thomas E. Dickey +Date: Wed Oct 30 19:16:09 2024 -0400 + + add debug-logging for file.c, to help with analysis + + Signed-off-by: Thomas E. Dickey + +commit 8a1de722164f60aa721fdb8d70d56505e52f4bd6 +Author: Thomas E. Dickey +Date: Tue Oct 29 16:53:05 2024 -0400 + + add/use _XcursorLibraryLoadImages to pass resized-parameter when loading + + Signed-off-by: Thomas E. Dickey + +commit b00d7da27bd5dad244e076e55df27143a9a5b55f +Author: Thomas E. Dickey +Date: Tue Oct 29 16:44:17 2024 -0400 + + use resized-parameter where available when loading images + + Signed-off-by: Thomas E. Dickey + +commit 5cb505f21e0baec05f4eaa445663bad8cc1d0e5a +Author: Thomas E. Dickey +Date: Tue Oct 29 16:36:57 2024 -0400 + + provide internal variants of existing functions to pass "resized" parameter + + Signed-off-by: Thomas E. Dickey + +commit e7272c804610bbc61a751b6faf5744028c4e9c3f +Author: Thomas E. Dickey +Date: Tue Oct 29 16:10:51 2024 -0400 + + restore behavior of image-loading, provide resizing via internal function + + Signed-off-by: Thomas E. Dickey + +commit 6816ed58e9217a70734137e3c934de1fa8588866 +Author: Thomas E. Dickey +Date: Tue Oct 29 04:07:17 2024 -0400 + + add getter/setter for "resized" property + + Signed-off-by: Thomas E. Dickey + +commit e5e63e2ba8395c538ca1377323bbc8879bcfd696 +Author: Thomas E. Dickey +Date: Tue Oct 29 04:01:49 2024 -0400 + + add new property "resized" and environment "XCURSOR_RESIZED" + + Signed-off-by: Thomas E. Dickey + +commit a5739d863beec78719cf1667382fc2323ff76481 +Author: Thomas E. Dickey +Date: Sun Oct 27 19:17:19 2024 -0400 + + trim redundant code from the resize-calls + + Signed-off-by: Thomas E. Dickey + +commit e1b6d3abb4bf09f42e8144e019a322a9a39e043f +Author: Thomas E. Dickey +Date: Sun Oct 27 12:49:16 2024 -0400 + + improve manpage formatting + + Signed-off-by: Thomas E. Dickey + +commit 7e03738efd6d19c141e8a4e0a59a9b628ffa7fd8 +Author: Thomas E. Dickey +Date: Sun Oct 27 10:12:52 2024 -0400 + + fix compiler warnings + + Signed-off-by: Thomas E. Dickey + +commit b09856069ce80409c7b03f13a96584a820898bff +Author: Thomas E. Dickey +Date: Sun Oct 27 06:40:18 2024 -0400 + + build-fix + + Signed-off-by: Thomas E. Dickey + +commit dfc856124754c3638460adbecc74dfe7e41987ce +Author: Jin Liu +Date: Fri Oct 11 10:51:47 2024 +0800 + + Remove unnecessary MIN calls + +commit a21cdaf167f449f7c9eb2baab4150ea864d8c8da +Author: Jin Liu +Date: Thu Oct 10 11:43:30 2024 +0800 + + Change all *LoadImage(..., size) APIs to always return a cursor with the requested size. + + Callers of these APIs (especially on Wayland) currently uses different + strategies to scale the returned cursor to the size set by the user, + resulting in inconsistent cursor sizes and looks across different apps + and toolkits. Having the cursor scaled in libXcursor will skip app's + own scaling algorithm and guarantee a consistent look. + + `*LoadAllImages()` are not changed. They still only return the sizes present + in the theme. + + This change needs to be synchronized to libraries (libxcb-cursor, wayland), + toolkits (GTK), window managers / Wayland compositors (i3, wlroots) who have + a (modified) copy of libXcursor source code, in order to have a fully consistent + cursor size across all apps. + + Signed-off-by: Jin Liu + +commit 833735e3232e28153411b3703dfe51883edf47ea +Author: Tobias Stoeckmann +Date: Thu Sep 12 22:23:50 2024 +0200 + + Ignore invalid cursor files + + If a cursor file contains a header offset which is too small, ignore + the file instead of jumping to an incorrect offset. + + Signed-off-by: Tobias Stoeckmann + commit 09617bcc9a0f1b5072212da5f8fede92ab85d157 Author: Alan Coopersmith Date: Sat Mar 2 12:55:30 2024 -0800 diff --git a/lib/libXcursor/Makefile.bsd-wrapper b/lib/libXcursor/Makefile.bsd-wrapper index eb5febc7e..c332243b5 100644 --- a/lib/libXcursor/Makefile.bsd-wrapper +++ b/lib/libXcursor/Makefile.bsd-wrapper @@ -1,6 +1,6 @@ -# $OpenBSD: Makefile.bsd-wrapper,v 1.5 2013/08/13 07:07:14 guenther Exp $ +# $OpenBSD: Makefile.bsd-wrapper,v 1.6 2024/11/11 09:26:22 matthieu Exp $ -SHARED_LIBS= Xcursor 5.0 +SHARED_LIBS= Xcursor 5.1 CONFIGURE_ARGS+= --with-cursorpath="~/.icons:/usr/local/lib/X11/icons:/usr/local/share/icons:/usr/local/share/pixmaps:${X11BASE}/share/icons:${X11BASE}/share/pixmaps" diff --git a/lib/libXcursor/configure b/lib/libXcursor/configure index 93cc51b3f..4923a11e9 100644 --- a/lib/libXcursor/configure +++ b/lib/libXcursor/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.71 for libXcursor 1.2.2. +# Generated by GNU Autoconf 2.71 for libXcursor 1.2.3. # # Report bugs to . # @@ -622,8 +622,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='libXcursor' PACKAGE_TARNAME='libXcursor' -PACKAGE_VERSION='1.2.2' -PACKAGE_STRING='libXcursor 1.2.2' +PACKAGE_VERSION='1.2.3' +PACKAGE_STRING='libXcursor 1.2.3' PACKAGE_BUGREPORT='https://gitlab.freedesktop.org/xorg/lib/libxcursor/-/issues' PACKAGE_URL='' @@ -1391,7 +1391,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures libXcursor 1.2.2 to adapt to many kinds of systems. +\`configure' configures libXcursor 1.2.3 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1462,7 +1462,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of libXcursor 1.2.2:";; + short | recursive ) echo "Configuration of libXcursor 1.2.3:";; esac cat <<\_ACEOF @@ -1593,7 +1593,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -libXcursor configure 1.2.2 +libXcursor configure 1.2.3 generated by GNU Autoconf 2.71 Copyright (C) 2021 Free Software Foundation, Inc. @@ -1863,7 +1863,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by libXcursor $as_me 1.2.2, which was +It was created by libXcursor $as_me 1.2.3, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw @@ -4337,7 +4337,7 @@ fi # Define the identity of the package. PACKAGE='libXcursor' - VERSION='1.2.2' + VERSION='1.2.3' printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h @@ -19256,7 +19256,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by libXcursor $as_me 1.2.2, which was +This file was extended by libXcursor $as_me 1.2.3, which was generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -19324,7 +19324,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -libXcursor config.status 1.2.2 +libXcursor config.status 1.2.3 configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" diff --git a/lib/libXcursor/configure.ac b/lib/libXcursor/configure.ac index d1699bf6f..8eda92ae9 100644 --- a/lib/libXcursor/configure.ac +++ b/lib/libXcursor/configure.ac @@ -26,7 +26,7 @@ AC_PREREQ([2.60]) # This is the package version number, not the shared library # version. This version number will be substituted into Xcursor.h # -AC_INIT([libXcursor], [1.2.2], +AC_INIT([libXcursor], [1.2.3], [https://gitlab.freedesktop.org/xorg/lib/libxcursor/-/issues], [libXcursor]) AC_CONFIG_SRCDIR([Makefile.am]) diff --git a/lib/libXcursor/include/X11/Xcursor/Xcursor.h.in b/lib/libXcursor/include/X11/Xcursor/Xcursor.h.in index 36400bf8c..a4999578a 100644 --- a/lib/libXcursor/include/X11/Xcursor/Xcursor.h.in +++ b/lib/libXcursor/include/X11/Xcursor/Xcursor.h.in @@ -1,4 +1,5 @@ /* + * Copyright © 2024 Thomas E. Dickey * Copyright © 2002 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its @@ -483,6 +484,12 @@ XcursorSetDefaultSize (Display *dpy, int size); int XcursorGetDefaultSize (Display *dpy); +XcursorBool +XcursorSetResizable (Display *dpy, XcursorBool flag); + +XcursorBool +XcursorGetResizable (Display *dpy); + XcursorBool XcursorSetTheme (Display *dpy, const char *theme); diff --git a/lib/libXcursor/m4/libtool.m4 b/lib/libXcursor/m4/libtool.m4 index 79a2451ef..e7b683345 100644 --- a/lib/libXcursor/m4/libtool.m4 +++ b/lib/libXcursor/m4/libtool.m4 @@ -730,7 +730,6 @@ _LT_CONFIG_SAVE_COMMANDS([ cat <<_LT_EOF >> "$cfgfile" #! $SHELL # Generated automatically by $as_me ($PACKAGE) $VERSION -# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # Provide generalized library-building support services. @@ -2907,6 +2906,18 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) dynamic_linker='GNU/Linux ld.so' ;; +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + netbsd*) version_type=sunos need_lib_prefix=no @@ -3566,7 +3577,7 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; -netbsd*) +netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' else @@ -4072,7 +4083,8 @@ _LT_EOF if AC_TRY_EVAL(ac_compile); then # Now try to grab the symbols. nlist=conftest.nm - if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then + $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&AS_MESSAGE_LOG_FD + if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&AS_MESSAGE_LOG_FD && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" @@ -4444,7 +4456,7 @@ m4_if([$1], [CXX], [ ;; esac ;; - netbsd*) + netbsd* | netbsdelf*-gnu) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise @@ -4712,6 +4724,12 @@ m4_if([$1], [CXX], [ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; + # flang / f18. f95 an alias for gfortran or flang on Debian + flang* | f18* | f95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) @@ -4956,6 +4974,9 @@ m4_if([$1], [CXX], [ ;; esac ;; + linux* | k*bsd*-gnu | gnu*) + _LT_TAGVAR(link_all_deplibs, $1)=no + ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; @@ -5018,6 +5039,9 @@ dnl Note also adjust exclude_expsyms for C++ above. openbsd* | bitrig*) with_gnu_ld=no ;; + linux* | k*bsd*-gnu | gnu*) + _LT_TAGVAR(link_all_deplibs, $1)=no + ;; esac _LT_TAGVAR(ld_shlibs, $1)=yes @@ -5253,6 +5277,7 @@ _LT_EOF case $cc_basename in tcc*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic' ;; xlf* | bgf* | bgxlf* | mpixlf*) @@ -5273,7 +5298,7 @@ _LT_EOF fi ;; - netbsd*) + netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= @@ -5794,6 +5819,7 @@ _LT_EOF if test yes = "$lt_cv_irix_exported_symbol"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' fi + _LT_TAGVAR(link_all_deplibs, $1)=no else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' @@ -5811,11 +5837,12 @@ _LT_EOF # Fabrice Bellard et al's Tiny C Compiler _LT_TAGVAR(ld_shlibs, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ;; esac ;; - netbsd*) + netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else @@ -6442,7 +6469,7 @@ if test yes != "$_lt_caught_CXX_error"; then # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else GXX=no @@ -6818,7 +6845,7 @@ if test yes != "$_lt_caught_CXX_error"; then # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then @@ -6883,7 +6910,7 @@ if test yes != "$_lt_caught_CXX_error"; then # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then @@ -7222,7 +7249,7 @@ if test yes != "$_lt_caught_CXX_error"; then # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else # FIXME: insert proper C++ library support @@ -7306,7 +7333,7 @@ if test yes != "$_lt_caught_CXX_error"; then # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else # g++ 2.7 appears to require '-G' NOT '-shared' on this # platform. @@ -7317,7 +7344,7 @@ if test yes != "$_lt_caught_CXX_error"; then # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir' diff --git a/lib/libXcursor/man/Xcursor.man b/lib/libXcursor/man/Xcursor.man index 84980ce20..a847917f2 100644 --- a/lib/libXcursor/man/Xcursor.man +++ b/lib/libXcursor/man/Xcursor.man @@ -1,5 +1,5 @@ .\" -.\" Copyright © 2021 Thomas E. Dickey +.\" Copyright © 2021,2024 Thomas E. Dickey .\" Copyright © 2002 Keith Packard .\" .\" Permission to use, copy, modify, distribute, and sell this software and @@ -25,14 +25,17 @@ .el .ta 0.5i 1.0i 1.5i 2.0i .. .de PS -.sp .ns -.TP \\$1 +.TP .na .nf .ie n .ta 0.8i 3.0i .el .ta 0.5i 2.0i .. +.de PC +.sp +.PS +.. .de PE .br .ad @@ -71,8 +74,8 @@ .TH XCURSOR __libmansuffix__ __xorgversion__ "X Version 11" .hy 0 .SH NAME -Xcursor \- Cursor management library -. +Xcursor \- +Cursor management library .SH SYNOPSIS .nf .B #include @@ -99,7 +102,7 @@ to use the Render extension CreateCursor request if supported by the X server. Where not supported, Xcursor maps the cursor image to a standard X cursor and uses the core CreateCursor request. . -.SS CURSOR FILES +.SS "CURSOR FILES" Xcursor defines a new format for cursors on disk. Each file holds one or more cursor images. @@ -121,7 +124,7 @@ The file header looks like: \fIversion\fP\^: CARD32 file version number \fIntoc\fP\^: CARD32 number of toc entries \fItoc\fP\^: LISTofTOC table of contents -.in -.2i +.QE .P Each table of contents entry looks like: .LP @@ -131,7 +134,6 @@ Each table of contents entry looks like: \fIposition\fP\^: CARD32 absolute byte position of table in file .QE .P -.P Each chunk in the file has set of common header fields followed by additional type-specific fields: .LP @@ -194,7 +196,7 @@ Within the theme directory, it looks for cursor files in the \*(``cursors\*('' subdirectory. .IP Xcursor looks for a specific file, -which must be one of the cursor \fIshape\fP names, +which must be one of the cursor \fIshape\fP names, e.g., as used in XcursorLibraryLoadImage or XcursorLibraryShape. .bP If it finds no matching cursor file in the \*(``cursors\*('' subdirectory, @@ -308,16 +310,15 @@ typedef struct _XcursorFile { int (*seek) (XcursorFile *file, long offset, int whence); }; .QE -.fi . .SH FUNCTIONS . -.SS Object Management +.SS "Object Management" .PS XcursorImage *XcursorImageCreate ( int \fIwidth\fP, int \fIheight\fP) -.PS +.PC void XcursorImageDestroy ( XcursorImage *\fIimage\fP) .PE @@ -328,7 +329,7 @@ The size is set to the maximum of \fIwidth\fP and \fIheight\fP. .PS XcursorImages *XcursorImagesCreate ( int \fIsize\fP) -.PS +.PC void XcursorImagesDestroy ( XcursorImages *\fIimages\fP) .PE @@ -339,7 +340,7 @@ On allocation, \fInimage\fP is set to zero. XcursorCursors *XcursorCursorsCreate ( Display *\fIdpy\fP, int \fIsize\fP) -.PS +.PC void XcursorCursorsDestroy ( XcursorCursors *\fIcursors\fP) .PE @@ -347,25 +348,25 @@ Allocate and free arrays to hold multiple cursors. On allocation, \fIncursor\fP is set to zero, \fIref\fP is set to one. . . -.SS Reading and writing images. +.SS "Reading and writing images" . .PS XcursorImage *XcursorXcFileLoadImage ( XcursorFile *\fIfile\fP, int \fIsize\fP) -.PS +.PC XcursorImages *XcursorXcFileLoadImages ( XcursorFile *\fIfile\fP, int \fIsize\fP) -.PS +.PC XcursorImages *XcursorXcFileLoadAllImages ( XcursorFile *\fIfile\fP) -.PS +.PC XcursorBool XcursorXcFileLoad ( XcursorFile *\fIfile\fP, XcursorComments **\fIcommentsp\fP, XcursorImages **\fIimagesp\fP) -.PS +.PC XcursorBool XcursorXcFileSave ( XcursorFile *\fIfile\fP, const XcursorComments *\fIcomments\fP, @@ -378,23 +379,23 @@ After reading, the file pointer will be left at some random place in the file. XcursorImage *XcursorFileLoadImage ( FILE *\fIfile\fP, int \fIsize\fP) -.PS +.PC XcursorImages *XcursorFileLoadImages ( FILE *\fIfile\fP, int \fIsize\fP) -.PS +.PC XcursorImages *XcursorFileLoadAllImages ( FILE *\fIfile\fP) -.PS +.PC XcursorBool XcursorFileLoad ( FILE *\fIfile\fP, XcursorComments **\fIcommentsp\fP, XcursorImages **\fIimagesp\fP) -.PS +.PC XcursorBool XcursorFileSaveImages ( FILE *\fIfile\fP, const XcursorImages *\fIimages\fP) -.PS +.PC XcursorBool XcursorFileSave ( FILE *\fIfile\fP, const XcursorComments *\fIcomments\fP, @@ -407,23 +408,23 @@ Writing flushes before returning so that any errors should be detected. XcursorImage *XcursorFilenameLoadImage ( const char *\fIfilename\fP, int \fIsize\fP) -.PS +.PC XcursorImages *XcursorFilenameLoadImages ( const char *\fIfilename\fP, int \fIsize\fP) -.PS +.PC XcursorImages *XcursorFilenameLoadAllImages ( const char *\fIfile\fP) -.PS +.PC XcursorBool XcursorFilenameLoad ( const char *\fIfile\fP, XcursorComments **\fIcommentsp\fP, XcursorImages **\fIimagesp\fP) -.PS +.PC XcursorBool XcursorFilenameSaveImages ( const char *\fIfilename\fP, const XcursorImages *\fIimages\fP) -.PS +.PC XcursorBool XcursorFilenameSave ( const char *\fIfile\fP, const XcursorComments *\fIcomments\fP, @@ -431,13 +432,13 @@ XcursorBool XcursorFilenameSave ( .PE These parallel the stdio FILE interfaces above, but take filenames. . -.SS Reading library images +.SS "Reading library images" .PS XcursorImage *XcursorLibraryLoadImage ( const char *\fIname\fP, const char *\fItheme\fP, int \fIsize\fP) -.PS +.PC XcursorImages *XcursorLibraryLoadImages ( const char *\fIname\fP, const char *\fItheme\fP, @@ -467,7 +468,7 @@ and (on success) it calls XcursorImagesSetName to associate \fIname\fP with the result. .RE . -.SS Library attributes +.SS "Library attributes" .PS const char * XcursorLibraryPath (void) .PE @@ -480,7 +481,7 @@ return that value. Otherwise, return the compiled-in search path. .RE . -.PS +.PC int XcursorLibraryShape ( const char *\fIlibrary\fP) .PE @@ -495,13 +496,13 @@ used in an X cursor font). If not found, return -1. .RE . -.SS Cursor APIs +.SS "Cursor APIs" . .PS Cursor XcursorFilenameLoadCursor ( Display *\fIdpy\fP, const char *\fIfile\fP) -.PS +.PC XcursorCursors *XcursorFilenameLoadCursors ( Display *\fIdpy\fP, const char *\fIfile\fP) @@ -512,7 +513,7 @@ These load cursors from the specified file. Cursor XcursorLibraryLoadCursor ( Display *\fIdpy\fP, const char *\fIname\fP) -.PS +.PC XcursorCursors *XcursorLibraryLoadCursors ( Display *\fIdpy\fP, const char *\fIname\fP) @@ -534,7 +535,7 @@ XRenderCreateCursor is used if ARGB is supported on the display, and XCreatePixmapCursor is used otherwise. .RE . -.PS +.PC Cursor XcursorImagesLoadCursor( Display *\fIdpy\fP, const XcursorImages *\fIimages\fP) @@ -557,14 +558,14 @@ Normally it returns the resulting array pointer. On any failure, it discards the result XcursorCursorsDestroy, and returns NULL. . -.SS X Cursor Name APIs +.SS "X Cursor Name APIs" . .PS XcursorImage *XcursorShapeLoadImage ( unsigned int \fIshape\fP, const char *\fItheme\fP, int \fIsize\fP) -.PS +.PC XcursorImages *XcursorShapeLoadImages ( unsigned int \fIshape\fP, const char *\fItheme\fP, @@ -577,14 +578,14 @@ then load the images. Cursor XcursorShapeLoadCursor ( Display *\fIdpy\fP, unsigned int \fIshape\fP) -.PS +.PC XcursorCursors *XcursorShapeLoadCursors ( Display *\fIdpy\fP, unsigned int \fIshape\fP) .PE These map \fIshape\fP to a library name and then load the cursors. . -.SS X Cursor Comment APIs +.SS "X Cursor Comment APIs" .PS XcursorComment *XcursorCommentCreate ( XcursorUInt \fIcomment_type\fP, @@ -617,7 +618,7 @@ void XcursorCommentsDestroy ( Deallocates the given XcursorComments structure as well as the XcursorComment structures which it points to. . -.SS Animated Cursors +.SS "Animated Cursors" .PS XcursorAnimate * XcursorAnimateCreate ( XcursorCursors *\fIcursors\fP) @@ -643,7 +644,7 @@ incrementing the sequence number to prepare for the next call. The caller is responsible for displaying the series of Cursor images. Xcursor does not do that. . -.SS Glyph Cursor APIs +.SS "Glyph Cursor APIs" The X11 XCreateFontCursor and XCreateGlyphCursor functions use this part of the API to extend the X core cursors feature to use themes. .PS @@ -727,7 +728,7 @@ Xcursor calls XcursorShapeLoadImages to load the cursor images. If successful, Xcursor uses XcursorImagesLoadCursor to load the cursor information. . -.SS Display Information APIs +.SS "Display Information APIs" . .PS XcursorBool XcursorSupportsARGB ( @@ -759,6 +760,20 @@ int XcursorGetDefaultSize ( Gets the default cursor size. . .PS +XcursorBool XcursorSetResizable ( + Display *\fIdpy\fP, + XcursorBool \fIresizable\fP) +.PE +Sets the current resizable-cursors state. +. +.PS +XcursorBool XcursorGetResizable ( + Display *\fIdpy\fP) +.PE +Gets the current resizable-cursors state. +. +. +.PS XcursorBool XcursorSetTheme ( Display *\fIdpy\fP, const char *\fItheme\fP) @@ -771,18 +786,18 @@ char *XcursorGetTheme ( .PE Gets the current theme name. . -.PS +.PC XcursorBool XcursorGetThemeCore ( Display *\fIdpy\fP) -.PS +.PC XcursorBool XcursorSetThemeCore ( Display *\fIdpy\fP, XcursorBool \fItheme_core\fP) .PE -Get or set property which tells Xcursor whether to +Get or set property which tells Xcursor whether to enable themes for core cursors. . -.SH "ENVIRONMENT VARIABLES" +.SH ENVIRONMENT Environment variables can be used to override resource settings, which in turn override compiled-in default values. .PP @@ -850,6 +865,13 @@ rather than the compiled-in default list. .IP Directories in this path are separated by colons (:). .TP 15 +.B XCURSOR_RESIZED +Enables automatic resizing of cursors to improve their displayed size +if the environment variable is \fItrue\fP. +.IP +If the environment variable is not given, +Xcursor tries the \fBXcursor.resized\fP resource. +.TP 15 .B XCURSOR_SIZE This variable sets the desired cursor size, in pixels. .IP @@ -881,6 +903,15 @@ Xcursor tries the \fBXcursor.theme_core\fP resource. .IP An application can enable or disable themes using XcursorSetThemeCore. . +.SH CAVEATS +.B Xcursor +will probably change radically in the future; weak attempts will be made to +retain some level of source-file compatibility. +. +.SH AUTHORS +Keith Packard +Thomas E. Dickey +. .SH SEE ALSO .na XCreateRenderCursor(__libmansuffix__), @@ -893,11 +924,3 @@ as well as \fIIcon Theme Specification\fP .br https://specifications.freedesktop.org/icon-theme-spec/ -. -.SH RESTRICTIONS -.B Xcursor -will probably change radically in the future; weak attempts will be made to -retain some level of source-file compatibility. -. -.SH AUTHOR -Keith Packard diff --git a/lib/libXcursor/src/cursor.c b/lib/libXcursor/src/cursor.c index 2e4d82193..905223c87 100644 --- a/lib/libXcursor/src/cursor.c +++ b/lib/libXcursor/src/cursor.c @@ -1,4 +1,5 @@ /* + * Copyright © 2024 Thomas E. Dickey * Copyright © 2002 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its @@ -742,9 +743,11 @@ Cursor XcursorFilenameLoadCursor (Display *dpy, const char *file) { int size = XcursorGetDefaultSize (dpy); - XcursorImages *images = XcursorFilenameLoadImages (file, size); + XcursorBool resize = XcursorGetResizable (dpy); + XcursorImages *images; Cursor cursor; + images = _XcursorFilenameLoadImages (file, size, resize); if (!images) return None; cursor = XcursorImagesLoadCursor (dpy, images); @@ -756,9 +759,11 @@ XcursorCursors * XcursorFilenameLoadCursors (Display *dpy, const char *file) { int size = XcursorGetDefaultSize (dpy); - XcursorImages *images = XcursorFilenameLoadImages (file, size); + XcursorBool resize = XcursorGetResizable (dpy); + XcursorImages *images; XcursorCursors *cursors; + images = _XcursorFilenameLoadImages (file, size, resize); if (!images) return NULL; cursors = XcursorImagesLoadCursors (dpy, images); diff --git a/lib/libXcursor/src/display.c b/lib/libXcursor/src/display.c index a61b5fd4e..a542a5195 100644 --- a/lib/libXcursor/src/display.c +++ b/lib/libXcursor/src/display.c @@ -1,4 +1,5 @@ /* + * Copyright © 2024 Thomas E. Dickey * Copyright © 2002 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its @@ -23,6 +24,7 @@ #include "xcursorint.h" #include #include +#include /* for getpid */ static XcursorDisplayInfo *_XcursorDisplayInfo; @@ -137,6 +139,14 @@ _XcursorGetDisplayInfo (Display *dpy) } (void) XESetCloseDisplay (dpy, info->codes->extension, _XcursorCloseDisplay); + /* + * The debugging-trace for new info-blocks begins here. + * As a reminder that multiple processes/threads use this library, + * the current process-id is logged. + */ + traceOpts((T_CALLED(_XcursorGetDisplayInfo) " info %p, pid %d\n", + (void*)info, getpid())); + /* * Check whether the display supports the Render CreateCursor request */ @@ -153,6 +163,7 @@ _XcursorGetDisplayInfo (Display *dpy) v = XGetDefault (dpy, "Xcursor", "core"); if (v && _XcursorDefaultParseBool (v) == 1) info->has_render_cursor = XcursorFalse; + traceOpts((T_OPTION(XCURSOR_CORE) ": %d\n", info->has_render_cursor)); } if (info->has_render_cursor && (major > 0 || minor >= 8)) { @@ -162,6 +173,7 @@ _XcursorGetDisplayInfo (Display *dpy) v = XGetDefault (dpy, "Xcursor", "anim"); if (v && _XcursorDefaultParseBool (v) == 0) info->has_anim_cursor = XcursorFalse; + traceOpts((T_OPTION(XCURSOR_ANIM) ": %d\n", info->has_anim_cursor)); } } @@ -175,6 +187,7 @@ _XcursorGetDisplayInfo (Display *dpy) v = XGetDefault (dpy, "Xcursor", "size"); if (v) info->size = atoi (v); + traceOpts((T_OPTION(XCURSOR_SIZE) ": %d\n", info->size)); /* * Use the Xft size to guess a size; make cursors 16 "points" tall @@ -187,6 +200,7 @@ _XcursorGetDisplayInfo (Display *dpy) dpi = atoi (v); if (dpi) info->size = dpi * 16 / 72; + traceOpts((T_OPTION(XCURSOR_SIZE) ": %d\n", info->size)); } /* @@ -205,11 +219,27 @@ _XcursorGetDisplayInfo (Display *dpy) * 16 pixels on a display of dimension 768 */ info->size = dim / 48; + traceOpts((T_OPTION(XCURSOR_SIZE) ": %d\n", info->size)); } info->theme = NULL; info->theme_from_config = NULL; + /* + * Provide for making cursors resized to match the requested size + */ + info->resized_cursors = XcursorFalse; + v = getenv ("XCURSOR_RESIZED"); + if (!v) + v = XGetDefault (dpy, "Xcursor", "resized"); + if (v) + { + i = _XcursorDefaultParseBool (v); + if (i >= 0) + info->resized_cursors = i; + } + traceOpts((T_OPTION(XCURSOR_RESIZED) ": %d\n", info->resized_cursors)); + /* * Get the desired theme */ @@ -221,6 +251,7 @@ _XcursorGetDisplayInfo (Display *dpy) info->theme = strdup (v); info->theme_from_config = strdup (v); } + traceOpts((T_OPTION(XCURSOR_THEME) ": %s\n", NonNull(info->theme))); /* * Get the desired dither @@ -240,6 +271,7 @@ _XcursorGetDisplayInfo (Display *dpy) if (!strcmp (v, "diffuse")) info->dither = XcursorDitherDiffuse; } + traceOpts((T_OPTION(XCURSOR_DITHER) ": %d\n", info->dither)); info->theme_core = False; /* @@ -255,6 +287,7 @@ _XcursorGetDisplayInfo (Display *dpy) if (i >= 0) info->theme_core = i; } + traceOpts((T_OPTION(XCURSOR_THEME_CORE) ": %d\n", info->theme_core)); info->fonts = NULL; for (i = 0; i < NUM_BITMAPS; i++) @@ -281,7 +314,7 @@ _XcursorGetDisplayInfo (Display *dpy) } _XUnlockMutex (_Xglobal_lock); - return info; + returnAddr(info); } XcursorBool @@ -321,6 +354,27 @@ XcursorGetDefaultSize (Display *dpy) return info->size; } +XcursorBool +XcursorSetResizable (Display *dpy, XcursorBool flag) +{ + XcursorDisplayInfo *info = _XcursorGetDisplayInfo (dpy); + + if (!info) + return XcursorFalse; + info->resized_cursors = flag; + return XcursorTrue; +} + +XcursorBool +XcursorGetResizable (Display *dpy) +{ + XcursorDisplayInfo *info = _XcursorGetDisplayInfo (dpy); + + if (!info) + return 0; + return info->resized_cursors; +} + XcursorBool XcursorSetTheme (Display *dpy, const char *theme) { @@ -365,7 +419,6 @@ XcursorGetThemeCore (Display *dpy) if (!info) return XcursorFalse; return info->theme_core; - } XcursorBool diff --git a/lib/libXcursor/src/file.c b/lib/libXcursor/src/file.c index 496d44707..8ffb341dd 100644 --- a/lib/libXcursor/src/file.c +++ b/lib/libXcursor/src/file.c @@ -1,4 +1,5 @@ /* + * Copyright © 2024 Thomas E. Dickey * Copyright © 2002 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its @@ -24,33 +25,90 @@ #include #include -XcursorImage * -XcursorImageCreate (int width, int height) +#ifdef DEBUG_XCURSOR +#include +#include +#include +void _XcursorTrace(const char *fmt, ...) { - XcursorImage *image; + FILE *fp = fopen("/tmp/xcursor.log", "a"); + if (fp != NULL) { + unsigned save = umask(0); + va_list ap; + va_start(ap, fmt); + vfprintf(fp, fmt, ap); + va_end(ap); + fclose(fp); + umask(save); + } +} + +void *_XcursorReturnAddr(void *addr) +{ + _XcursorTrace(T_RETURN(p), addr); + return addr; +} - if (width < 0 || height < 0) - return NULL; - if (width > XCURSOR_IMAGE_MAX_SIZE || height > XCURSOR_IMAGE_MAX_SIZE) - return NULL; +int _XcursorReturnCode(int code) +{ + _XcursorTrace(T_RETURN(d), code); + return code; +} - image = malloc (sizeof (XcursorImage) + - (size_t) (width * height) * sizeof (XcursorPixel)); - if (!image) - return NULL; - image->version = XCURSOR_IMAGE_VERSION; - image->pixels = (XcursorPixel *) (image + 1); - image->size = (XcursorDim) (width > height ? width : height); - image->width = (XcursorDim) width; - image->height = (XcursorDim) height; - image->delay = 0; - return image; +unsigned long _XcursorReturnLong(unsigned long code) +{ + _XcursorTrace(T_RETURN(lu), code); + return code; +} + +unsigned _XcursorReturnUint(unsigned code) +{ + _XcursorTrace(T_RETURN(u), code); + return code; +} + +void _XcursorReturnVoid(void) +{ + _XcursorTrace(T_RETURN(s), ""); + return; +} +#endif /* DEBUG_XCURSOR */ + +XcursorImage * +XcursorImageCreate (int width, int height) +{ + XcursorImage *image = NULL; + + enterFunc((T_CALLED(XcursorImageCreate) "(%d, %d)\n", width, height)); + + if (width < 0 || height < 0) { + /* EMPTY */; + } else if (width > XCURSOR_IMAGE_MAX_SIZE + || height > XCURSOR_IMAGE_MAX_SIZE) { + /* EMPTY */; + } else { + image = malloc (sizeof (XcursorImage) + + (size_t) (width * height) * sizeof (XcursorPixel)); + if (image) { + image->version = XCURSOR_IMAGE_VERSION; + image->pixels = (XcursorPixel *) (image + 1); + image->size = (XcursorDim) (width > height ? width : height); + image->width = (XcursorDim) width; + image->height = (XcursorDim) height; + image->delay = 0; + } + } + returnAddr(image); } void XcursorImageDestroy (XcursorImage *image) { + enterFunc((T_CALLED(XcursorImageDestroy ) "(%p)\n", (void*)image)); + free (image); + + returnVoid(); } XcursorImages * @@ -58,47 +116,54 @@ XcursorImagesCreate (int size) { XcursorImages *images; + enterFunc((T_CALLED(XcursorImagesCreate) "(%d)\n", size)); + images = malloc (sizeof (XcursorImages) + (size_t) size * sizeof (XcursorImage *)); - if (!images) - return NULL; - images->nimage = 0; - images->images = (XcursorImage **) (images + 1); - images->name = NULL; - return images; + if (images) { + images->nimage = 0; + images->images = (XcursorImage **) (images + 1); + images->name = NULL; + } + returnAddr(images); } void XcursorImagesDestroy (XcursorImages *images) { - int n; + enterFunc((T_CALLED(XcursorImagesDestroy) "(%p)\n", (void*)images)); - if (!images) - return; + if (images) { + int n; - for (n = 0; n < images->nimage; n++) - XcursorImageDestroy (images->images[n]); - if (images->name) - free (images->name); - free (images); + for (n = 0; n < images->nimage; n++) + XcursorImageDestroy (images->images[n]); + if (images->name) + free (images->name); + free (images); + } + + returnVoid(); } void XcursorImagesSetName (XcursorImages *images, const char *name) { - char *new; - - if (!images || !name) - return; + enterFunc((T_CALLED(XcursorImagesSetName) "(%p, \"%s\")\n", + (void*)images, + NonNull(name))); - new = strdup (name); + if (images && name) { + char *new = strdup (name); - if (!new) - return; + if (new) { + if (images->name) + free (images->name); + images->name = new; + } + } - if (images->name) - free (images->name); - images->name = new; + returnVoid(); } XcursorComment * @@ -145,7 +210,7 @@ XcursorCommentsDestroy (XcursorComments *comments) int n; if (!comments) - return; + return; for (n = 0; n < comments->ncomment; n++) XcursorCommentDestroy (comments->comments[n]); @@ -158,13 +223,13 @@ _XcursorReadUInt (XcursorFile *file, XcursorUInt *u) unsigned char bytes[4]; if (!file || !u) - return XcursorFalse; + return XcursorFalse; if ((*file->read) (file, bytes, 4) != 4) - return XcursorFalse; + return XcursorFalse; *u = ((XcursorUInt)(bytes[0]) << 0) | - ((XcursorUInt)(bytes[1]) << 8) | + ((XcursorUInt)(bytes[1]) << 8) | ((XcursorUInt)(bytes[2]) << 16) | ((XcursorUInt)(bytes[3]) << 24); return XcursorTrue; @@ -244,6 +309,8 @@ _XcursorReadFileHeader (XcursorFile *file) return NULL; if (!_XcursorReadUInt (file, &head.header)) return NULL; + if (head.header < XCURSOR_FILE_HEADER_LEN) + return NULL; if (!_XcursorReadUInt (file, &head.version)) return NULL; if (!_XcursorReadUInt (file, &head.ntoc)) @@ -380,8 +447,11 @@ _XcursorFindBestSize (XcursorFileHeader *fileHeader, XcursorDim bestSize = 0; XcursorDim thisSize; + enterFunc((T_CALLED(_XcursorFindBestSize) "(%p, %u, %p)\n", + (void*)fileHeader, size, (void*)nsizesp)); + if (!fileHeader || !nsizesp) - return 0; + returnUint(0); for (n = 0; n < fileHeader->ntoc; n++) { @@ -397,7 +467,7 @@ _XcursorFindBestSize (XcursorFileHeader *fileHeader, nsizes++; } *nsizesp = nsizes; - return bestSize; + returnUint(bestSize); } static int @@ -408,8 +478,11 @@ _XcursorFindImageToc (XcursorFileHeader *fileHeader, XcursorUInt toc; XcursorDim thisSize; + enterFunc((T_CALLED(_XcursorFindImageToc) "(%p, %u, %d)\n", + (void*)fileHeader, size, count)); + if (!fileHeader) - return 0; + returnCode(0); for (toc = 0; toc < fileHeader->ntoc; toc++) { @@ -423,8 +496,8 @@ _XcursorFindImageToc (XcursorFileHeader *fileHeader, count--; } if (toc == fileHeader->ntoc) - return -1; - return (int) toc; + returnCode(-1); + returnCode((int) toc); } static XcursorImage * @@ -438,34 +511,37 @@ _XcursorReadImage (XcursorFile *file, int n; XcursorPixel *p; + enterFunc((T_CALLED(_XcursorReadImage) "(%p, %p, %d)\n", + (void*)file, (void*)fileHeader, toc)); + if (!file || !fileHeader) - return NULL; + returnAddr(NULL); if (!_XcursorFileReadChunkHeader (file, fileHeader, toc, &chunkHeader)) - return NULL; + returnAddr(NULL); if (!_XcursorReadUInt (file, &head.width)) - return NULL; + returnAddr(NULL); if (!_XcursorReadUInt (file, &head.height)) - return NULL; + returnAddr(NULL); if (!_XcursorReadUInt (file, &head.xhot)) - return NULL; + returnAddr(NULL); if (!_XcursorReadUInt (file, &head.yhot)) - return NULL; + returnAddr(NULL); if (!_XcursorReadUInt (file, &head.delay)) - return NULL; + returnAddr(NULL); /* sanity check data */ if (head.width > XCURSOR_IMAGE_MAX_SIZE || head.height > XCURSOR_IMAGE_MAX_SIZE) - return NULL; + returnAddr(NULL); if (head.width == 0 || head.height == 0) - return NULL; + returnAddr(NULL); if (head.xhot > head.width || head.yhot > head.height) - return NULL; + returnAddr(NULL); /* Create the image and initialize it */ image = XcursorImageCreate ((int) head.width, (int) head.height); if (image == NULL) - return NULL; + returnAddr(NULL); if (chunkHeader.version < image->version) image->version = chunkHeader.version; image->size = chunkHeader.subtype; @@ -479,20 +555,22 @@ _XcursorReadImage (XcursorFile *file, if (!_XcursorReadUInt (file, p)) { XcursorImageDestroy (image); - return NULL; + returnAddr(NULL); } p++; } - return image; + returnAddr(image); } static XcursorUInt _XcursorImageLength (XcursorImage *image) { + enterFunc((T_CALLED(_XcursorImageLength) "(%p)\n", (void*)image)); + if (!image) - return 0; + returnUint(0); - return XCURSOR_IMAGE_HEADER_LEN + (image->width * image->height) * 4; + returnUint(XCURSOR_IMAGE_HEADER_LEN + (image->width * image->height) * 4); } static XcursorBool @@ -505,17 +583,20 @@ _XcursorWriteImage (XcursorFile *file, int n; XcursorPixel *p; + enterFunc((T_CALLED(_XcursorWriteImage) "(%p, %p, %d, %p)\n", + (void*)file, (void*)fileHeader, toc, (void*)image)); + if (!file || !fileHeader || !image) - return XcursorFalse; + returnCode(XcursorFalse); /* sanity check data */ if (image->width > XCURSOR_IMAGE_MAX_SIZE || image->height > XCURSOR_IMAGE_MAX_SIZE) - return XcursorFalse; + returnCode(XcursorFalse); if (image->width == 0 || image->height == 0) - return XcursorFalse; + returnCode(XcursorFalse); if (image->xhot > image->width || image->yhot > image->height) - return XcursorFalse; + returnCode(XcursorFalse); /* write chunk header */ chunkHeader.header = XCURSOR_IMAGE_HEADER_LEN; @@ -524,19 +605,19 @@ _XcursorWriteImage (XcursorFile *file, chunkHeader.version = XCURSOR_IMAGE_VERSION; if (!_XcursorFileWriteChunkHeader (file, fileHeader, toc, &chunkHeader)) - return XcursorFalse; + returnCode(XcursorFalse); /* write extra image header fields */ if (!_XcursorWriteUInt (file, image->width)) - return XcursorFalse; + returnCode(XcursorFalse); if (!_XcursorWriteUInt (file, image->height)) - return XcursorFalse; + returnCode(XcursorFalse); if (!_XcursorWriteUInt (file, image->xhot)) - return XcursorFalse; + returnCode(XcursorFalse); if (!_XcursorWriteUInt (file, image->yhot)) - return XcursorFalse; + returnCode(XcursorFalse); if (!_XcursorWriteUInt (file, image->delay)) - return XcursorFalse; + returnCode(XcursorFalse); /* write the image */ n = (int) (image->width * image->height); @@ -544,10 +625,10 @@ _XcursorWriteImage (XcursorFile *file, while (n--) { if (!_XcursorWriteUInt (file, *p)) - return XcursorFalse; + returnCode(XcursorFalse); p++; } - return XcursorTrue; + returnCode(XcursorTrue); } static XcursorComment * @@ -559,25 +640,28 @@ _XcursorReadComment (XcursorFile *file, XcursorUInt length; XcursorComment *comment; + enterFunc((T_CALLED(_XcursorReadComment) "(%p, %p, %d)\n", + (void*)file, (void*)fileHeader, toc)); + if (!file || !fileHeader) - return NULL; + returnAddr(NULL); /* read chunk header */ if (!_XcursorFileReadChunkHeader (file, fileHeader, toc, &chunkHeader)) - return NULL; + returnAddr(NULL); /* read extra comment header fields */ if (!_XcursorReadUInt (file, &length)) - return NULL; + returnAddr(NULL); comment = XcursorCommentCreate (chunkHeader.subtype, (int) length); if (!comment) - return NULL; + returnAddr(NULL); if (!_XcursorReadBytes (file, comment->comment, (int) length)) { XcursorCommentDestroy (comment); - return NULL; + returnAddr(NULL); } comment->comment[length] = '\0'; - return comment; + returnAddr(comment); } static XcursorUInt @@ -622,8 +706,42 @@ _XcursorWriteComment (XcursorFile *file, return XcursorTrue; } -XcursorImage * -XcursorXcFileLoadImage (XcursorFile *file, int size) +static XcursorImage * +_XcursorResizeImage (XcursorImage *src, int size) +{ + XcursorDim dest_y, dest_x; + double scale = (double) size / src->size; + XcursorImage *dest; + + enterFunc((T_CALLED(_XcursorResizeImage) "(%p, %d)\n", (void*)src, size)); + + dest = XcursorImageCreate ((int) (src->width * scale), + (int) (src->height * scale)); + if (!dest) + returnAddr(NULL); + + dest->size = (XcursorDim) size; + dest->xhot = (XcursorDim) (src->xhot * scale); + dest->yhot = (XcursorDim) (src->yhot * scale); + dest->delay = src->delay; + + for (dest_y = 0; dest_y < dest->height; dest_y++) + { + XcursorDim src_y = (XcursorDim) (dest_y / scale); + XcursorPixel *src_row = src->pixels + (src_y * src->width); + XcursorPixel *dest_row = dest->pixels + (dest_y * dest->width); + for (dest_x = 0; dest_x < dest->width; dest_x++) + { + XcursorDim src_x = (XcursorDim) (dest_x / scale); + dest_row[dest_x] = src_row[src_x]; + } + } + + returnAddr(dest); +} + +static XcursorImage * +_XcursorXcFileLoadImage (XcursorFile *file, int size, XcursorBool resize) { XcursorFileHeader *fileHeader; XcursorDim bestSize; @@ -631,66 +749,105 @@ XcursorXcFileLoadImage (XcursorFile *file, int size) int toc; XcursorImage *image; + enterFunc((T_CALLED(_XcursorXcFileLoadImage) "(%p, %d, %d)\n", + (void*)file, size, resize)); + if (size < 0) - return NULL; + returnAddr(NULL); fileHeader = _XcursorReadFileHeader (file); if (!fileHeader) - return NULL; + returnAddr(NULL); bestSize = _XcursorFindBestSize (fileHeader, (XcursorDim) size, &nsize); if (!bestSize) - return NULL; + returnAddr(NULL); toc = _XcursorFindImageToc (fileHeader, bestSize, 0); if (toc < 0) - return NULL; + returnAddr(NULL); image = _XcursorReadImage (file, fileHeader, toc); _XcursorFileHeaderDestroy (fileHeader); - return image; + + if (resize && image != NULL && (image->size != (XcursorDim) size)) + { + XcursorImage *resized_image = _XcursorResizeImage (image, size); + XcursorImageDestroy (image); + image = resized_image; + } + + returnAddr(image); +} + +XcursorImage * +XcursorXcFileLoadImage (XcursorFile *file, int size) +{ + enterFunc((T_CALLED(XcursorXcFileLoadImage) "(%p, %d)\n", (void*)file, size)); + + returnAddr(_XcursorXcFileLoadImage (file, size, XcursorFalse)); } XcursorImages * -XcursorXcFileLoadImages (XcursorFile *file, int size) +_XcursorXcFileLoadImages (XcursorFile *file, int size, XcursorBool resize) { XcursorFileHeader *fileHeader; XcursorDim bestSize; int nsize; XcursorImages *images; int n; + XcursorImage *image; + + enterFunc((T_CALLED(_XcursorXcFileLoadImages) "(%p, %d, %d)\n", + (void*)file, size, resize)); if (!file || size < 0) - return NULL; + returnAddr(NULL); fileHeader = _XcursorReadFileHeader (file); if (!fileHeader) - return NULL; + returnAddr(NULL); bestSize = _XcursorFindBestSize (fileHeader, (XcursorDim) size, &nsize); if (!bestSize) { _XcursorFileHeaderDestroy (fileHeader); - return NULL; + returnAddr(NULL); } images = XcursorImagesCreate (nsize); if (!images) { _XcursorFileHeaderDestroy (fileHeader); - return NULL; + returnAddr(NULL); } for (n = 0; n < nsize; n++) { int toc = _XcursorFindImageToc (fileHeader, bestSize, n); if (toc < 0) break; - images->images[images->nimage] = _XcursorReadImage (file, fileHeader, - toc); - if (!images->images[images->nimage]) + image = _XcursorReadImage (file, fileHeader, toc); + if (!image) break; + if (resize && (image->size != (XcursorDim) size)) + { + XcursorImage *resized_image = _XcursorResizeImage (image, size); + XcursorImageDestroy (image); + image = resized_image; + if (image == NULL) + break; + } + images->images[images->nimage] = image; images->nimage++; } _XcursorFileHeaderDestroy (fileHeader); - if (images->nimage != nsize) + if (images != NULL && images->nimage != nsize) { XcursorImagesDestroy (images); images = NULL; } - return images; + returnAddr(images); +} + +XcursorImages * +XcursorXcFileLoadImages (XcursorFile *file, int size) +{ + enterFunc((T_CALLED(XcursorXcFileLoadImages) "(%p, %d)\n", (void*)file, size)); + + returnAddr(_XcursorXcFileLoadImages (file, size, XcursorFalse)); } XcursorImages * @@ -703,12 +860,14 @@ XcursorXcFileLoadAllImages (XcursorFile *file) XcursorUInt n; XcursorUInt toc; + enterFunc((T_CALLED(XcursorXcFileLoadAllImages) "(%p)\n", (void*)file)); + if (!file) - return NULL; + returnAddr(NULL); fileHeader = _XcursorReadFileHeader (file); if (!fileHeader) - return NULL; + returnAddr(NULL); nimage = 0; for (n = 0; n < fileHeader->ntoc; n++) { @@ -722,7 +881,7 @@ XcursorXcFileLoadAllImages (XcursorFile *file) if (!images) { _XcursorFileHeaderDestroy (fileHeader); - return NULL; + returnAddr(NULL); } for (toc = 0; toc < fileHeader->ntoc; toc++) { @@ -743,7 +902,7 @@ XcursorXcFileLoadAllImages (XcursorFile *file) XcursorImagesDestroy (images); images = NULL; } - return images; + returnAddr(images); } XcursorBool @@ -760,11 +919,14 @@ XcursorXcFileLoad (XcursorFile *file, XcursorComments *comments; XcursorUInt toc; + enterFunc((T_CALLED(XcursorXcFileLoad) "(%p, %p, %p)\n", + (void*)file, (void*)commentsp, (void*)imagesp)); + if (!file) - return 0; + returnCode(0); fileHeader = _XcursorReadFileHeader (file); if (!fileHeader) - return 0; + returnCode(0); nimage = 0; ncomment = 0; for (toc = 0; toc < fileHeader->ntoc; toc++) @@ -782,14 +944,14 @@ XcursorXcFileLoad (XcursorFile *file, if (!images) { _XcursorFileHeaderDestroy (fileHeader); - return 0; + returnCode(0); } comments = XcursorCommentsCreate (ncomment); if (!comments) { _XcursorFileHeaderDestroy (fileHeader); XcursorImagesDestroy (images); - return 0; + returnCode(0); } for (toc = 0; toc < fileHeader->ntoc; toc++) { @@ -819,11 +981,11 @@ XcursorXcFileLoad (XcursorFile *file, XcursorCommentsDestroy (comments); images = NULL; comments = NULL; - return XcursorFalse; + returnCode(XcursorFalse); } *imagesp = images; *commentsp = comments; - return XcursorTrue; + returnCode(XcursorTrue); } XcursorBool @@ -833,15 +995,26 @@ XcursorXcFileSave (XcursorFile *file, { XcursorFileHeader *fileHeader; XcursorUInt position; - int n; + XcursorUInt n; int toc; + XcursorUInt ncomment; + XcursorUInt nimage; + + enterFunc((T_CALLED(XcursorXcFileSave) "(%p, %p, %p)\n", + (void*)file, (const void*)comments, (const void*)images)); if (!file || !comments || !images) - return XcursorFalse; + returnCode(XcursorFalse); - fileHeader = _XcursorFileHeaderCreate ((XcursorUInt) (comments->ncomment + images->nimage)); + /* + * Caller may have tainted the counts. + */ + ncomment = (XcursorUInt)(comments->ncomment > 0 ? comments->ncomment : 0); + nimage = (XcursorUInt)(images->nimage > 0 ? images->nimage : 0); + + fileHeader = _XcursorFileHeaderCreate (ncomment + nimage); if (!fileHeader) - return XcursorFalse; + returnCode(XcursorFalse); position = _XcursorFileHeaderLength (fileHeader); @@ -851,7 +1024,7 @@ XcursorXcFileSave (XcursorFile *file, */ toc = 0; - for (n = 0; n < images->nimage; n++) + for (n = 0; n < nimage; n++) { fileHeader->tocs[toc].type = XCURSOR_IMAGE_TYPE; fileHeader->tocs[toc].subtype = images->images[n]->size; @@ -860,7 +1033,7 @@ XcursorXcFileSave (XcursorFile *file, toc++; } - for (n = 0; n < comments->ncomment; n++) + for (n = 0; n < ncomment; n++) { fileHeader->tocs[toc].type = XCURSOR_COMMENT_TYPE; fileHeader->tocs[toc].subtype = comments->comments[n]->comment_type; @@ -879,7 +1052,7 @@ XcursorXcFileSave (XcursorFile *file, * Write the images */ toc = 0; - for (n = 0; n < images->nimage; n++) + for (n = 0; n < nimage; n++) { if (!_XcursorWriteImage (file, fileHeader, toc, images->images[n])) goto bail; @@ -889,7 +1062,7 @@ XcursorXcFileSave (XcursorFile *file, /* * Write the comments */ - for (n = 0; n < comments->ncomment; n++) + for (n = 0; n < ncomment; n++) { if (!_XcursorWriteComment (file, fileHeader, toc, comments->comments[n])) goto bail; @@ -897,10 +1070,11 @@ XcursorXcFileSave (XcursorFile *file, } _XcursorFileHeaderDestroy (fileHeader); - return XcursorTrue; + returnCode(XcursorTrue); + bail: _XcursorFileHeaderDestroy (fileHeader); - return XcursorFalse; + returnCode(XcursorFalse); } static int @@ -933,16 +1107,46 @@ _XcursorStdioFileInitialize (FILE *stdfile, XcursorFile *file) file->seek = _XcursorStdioFileSeek; } +XcursorImage * +_XcursorFileLoadImage (FILE *file, int size, XcursorBool resize) +{ + XcursorFile f; + + enterFunc((T_CALLED(_XcursorFileLoadImage) "(%p, %d, %d)\n", (void*)file, size, resize)); + + if (!file) + returnAddr(NULL); + + _XcursorStdioFileInitialize (file, &f); + returnAddr(_XcursorXcFileLoadImage (&f, size, resize)); +} + +XcursorImages * +_XcursorFileLoadImages (FILE *file, int size, XcursorBool resize) +{ + XcursorFile f; + + enterFunc((T_CALLED(_XcursorFileLoadImages) "(%p, %d, %d)\n", (void*)file, size, resize)); + + if (!file) + returnAddr(NULL); + + _XcursorStdioFileInitialize (file, &f); + returnAddr(_XcursorXcFileLoadImages (&f, size, resize)); +} + XcursorImage * XcursorFileLoadImage (FILE *file, int size) { XcursorFile f; + enterFunc((T_CALLED(XcursorFileLoadImage) "(%p, %d)\n", (void*)file, size)); + if (!file) - return NULL; + returnAddr(NULL); _XcursorStdioFileInitialize (file, &f); - return XcursorXcFileLoadImage (&f, size); + returnAddr(XcursorXcFileLoadImage (&f, size)); } XcursorImages * @@ -950,11 +1154,13 @@ XcursorFileLoadImages (FILE *file, int size) { XcursorFile f; + enterFunc((T_CALLED(XcursorFileLoadImages) "(%p, %d)\n", (void*)file, size)); + if (!file) - return NULL; + returnAddr(NULL); _XcursorStdioFileInitialize (file, &f); - return XcursorXcFileLoadImages (&f, size); + returnAddr(XcursorXcFileLoadImages (&f, size)); } XcursorImages * @@ -962,11 +1168,13 @@ XcursorFileLoadAllImages (FILE *file) { XcursorFile f; + enterFunc((T_CALLED(XcursorFileLoadAllImages) "(%p)\n", (void*)file)); + if (!file) - return NULL; + returnAddr(NULL); _XcursorStdioFileInitialize (file, &f); - return XcursorXcFileLoadAllImages (&f); + returnAddr(XcursorXcFileLoadAllImages (&f)); } XcursorBool @@ -976,11 +1184,14 @@ XcursorFileLoad (FILE *file, { XcursorFile f; + enterFunc((T_CALLED(XcursorFileLoad) "(%p, %p, %p)\n", + (void*)file, (void*)commentsp, (void*)imagesp)); + if (!file || !commentsp || !imagesp) - return XcursorFalse; + returnCode(XcursorFalse); _XcursorStdioFileInitialize (file, &f); - return XcursorXcFileLoad (&f, commentsp, imagesp); + returnCode(XcursorXcFileLoad (&f, commentsp, imagesp)); } XcursorBool @@ -990,14 +1201,17 @@ XcursorFileSaveImages (FILE *file, const XcursorImages *images) XcursorFile f; XcursorBool ret; + enterFunc((T_CALLED(XcursorFileSaveImages) "(%p, %p)\n", + (void*)file, (const void*)images)); + if (!file || !images) - return 0; + returnCode(0); if ((comments = XcursorCommentsCreate (0)) == NULL) - return 0; + returnCode(0); _XcursorStdioFileInitialize (file, &f); ret = XcursorXcFileSave (&f, comments, images) && fflush (file) != EOF; XcursorCommentsDestroy (comments); - return ret; + returnCode(ret); } XcursorBool @@ -1007,11 +1221,14 @@ XcursorFileSave (FILE * file, { XcursorFile f; + enterFunc((T_CALLED(_XcursorFileSave) "(%p, %p, %p)\n", + (void*)file, (const void*)comments, (const void*)images)); + if (!file || !comments || !images) - return XcursorFalse; + returnCode(XcursorFalse); _XcursorStdioFileInitialize (file, &f); - return XcursorXcFileSave (&f, comments, images) && fflush (file) != EOF; + returnCode(XcursorXcFileSave (&f, comments, images) && fflush (file) != EOF); } XcursorImage * @@ -1020,15 +1237,38 @@ XcursorFilenameLoadImage (const char *file, int size) FILE *f; XcursorImage *image; + enterFunc((T_CALLED(XcursorFilenameLoadImage) "(\"%s\", %d)\n", + NonNull(file), size)); + if (!file || size < 0) - return NULL; + returnAddr(NULL); f = fopen (file, "r" FOPEN_CLOEXEC); if (!f) - return NULL; + returnAddr(NULL); image = XcursorFileLoadImage (f, size); fclose (f); - return image; + returnAddr(image); +} + +XcursorImages * +_XcursorFilenameLoadImages (const char *file, int size, XcursorBool resize) +{ + FILE *f; + XcursorImages *images; + + enterFunc((T_CALLED(_XcursorFilenameLoadImages) "(\"%s\", %d, %d)\n", + NonNull(file), size, resize)); + + if (!file || size < 0) + returnAddr(NULL); + + f = fopen (file, "r" FOPEN_CLOEXEC); + if (!f) + returnAddr(NULL); + images = _XcursorFileLoadImages (f, size, resize); + fclose (f); + returnAddr(images); } XcursorImages * @@ -1037,15 +1277,18 @@ XcursorFilenameLoadImages (const char *file, int size) FILE *f; XcursorImages *images; + enterFunc((T_CALLED(XcursorFilenameLoadImages) "(\"%s\", %d)\n", + NonNull(file), size)); + if (!file || size < 0) - return NULL; + returnAddr(NULL); f = fopen (file, "r" FOPEN_CLOEXEC); if (!f) - return NULL; + returnAddr(NULL); images = XcursorFileLoadImages (f, size); fclose (f); - return images; + returnAddr(images); } XcursorImages * @@ -1054,15 +1297,18 @@ XcursorFilenameLoadAllImages (const char *file) FILE *f; XcursorImages *images; + enterFunc((T_CALLED(XcursorFilenameLoadAllImages) "(\"%s\")\n", + NonNull(file))); + if (!file) - return NULL; + returnAddr(NULL); f = fopen (file, "r" FOPEN_CLOEXEC); if (!f) - return NULL; + returnAddr(NULL); images = XcursorFileLoadAllImages (f); fclose (f); - return images; + returnAddr(images); } XcursorBool @@ -1073,15 +1319,18 @@ XcursorFilenameLoad (const char *file, FILE *f; XcursorBool ret; + enterFunc((T_CALLED() "(\"%s\", %p, %p)\n", + NonNull(file), (void*)commentsp, (void*)imagesp)); + if (!file) - return XcursorFalse; + returnCode(XcursorFalse); f = fopen (file, "r" FOPEN_CLOEXEC); if (!f) - return 0; + returnCode(0); ret = XcursorFileLoad (f, commentsp, imagesp); fclose (f); - return ret; + returnCode(ret); } XcursorBool @@ -1090,14 +1339,17 @@ XcursorFilenameSaveImages (const char *file, const XcursorImages *images) FILE *f; XcursorBool ret; + enterFunc((T_CALLED(XcursorFilenameSaveImages) "(\"%s\", %p)\n", + NonNull(file), (const void*)images)); + if (!file || !images) - return XcursorFalse; + returnCode(XcursorFalse); f = fopen (file, "w" FOPEN_CLOEXEC); if (!f) - return 0; + returnCode(0); ret = XcursorFileSaveImages (f, images); - return fclose (f) != EOF && ret; + returnCode(fclose (f) != EOF && ret); } XcursorBool @@ -1108,12 +1360,21 @@ XcursorFilenameSave (const char *file, FILE *f; XcursorBool ret; - if (!file || !comments || !images) - return XcursorFalse; - - f = fopen (file, "w" FOPEN_CLOEXEC); - if (!f) - return 0; - ret = XcursorFileSave (f, comments, images); - return fclose (f) != EOF && ret; + enterFunc((T_CALLED(XcursorFilenameSave ) "(\"%s\", %p, %p)\n", + NonNull(file), + (const void *) comments, + (const void *) images)); + + if (!file || !comments || !images) { + ret = XcursorFalse; + } else { + f = fopen (file, "w" FOPEN_CLOEXEC); + if (!f) { + ret = 0; + } else { + ret = XcursorFileSave (f, comments, images); + ret = fclose (f) != EOF && ret; + } + } + returnCode(ret); } diff --git a/lib/libXcursor/src/library.c b/lib/libXcursor/src/library.c index de2351569..85c500600 100644 --- a/lib/libXcursor/src/library.c +++ b/lib/libXcursor/src/library.c @@ -1,4 +1,5 @@ /* + * Copyright © 2024 Thomas E. Dickey * Copyright © 2002 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its @@ -47,6 +48,7 @@ XcursorLibraryPath (void) path = getenv ("XCURSOR_PATH"); if (!path) path = XCURSORPATH; + traceOpts((T_OPTION(XCURSOR_PATH) ": %s\n", NonNull(path))); } return path; } @@ -314,8 +316,11 @@ XcursorLibraryLoadImage (const char *file, const char *theme, int size) FILE *f = NULL; XcursorImage *image = NULL; + enterFunc((T_CALLED(XcursorLibraryLoadImage) "(\"%s\",\"%s\", %d)\n", + NonNull(file), NonNull(theme), size)); + if (!file) - return NULL; + returnAddr(NULL); if (theme) f = XcursorScanTheme (theme, file); @@ -326,7 +331,33 @@ XcursorLibraryLoadImage (const char *file, const char *theme, int size) image = XcursorFileLoadImage (f, size); fclose (f); } - return image; + returnAddr(image); +} + +static XcursorImages * +_XcursorLibraryLoadImages (Display *dpy, const char *file) +{ + int size = XcursorGetDefaultSize (dpy); + char *theme = XcursorGetTheme (dpy); + XcursorBool resized = XcursorGetResizable (dpy); + FILE *f = NULL; + XcursorImages *images = NULL; + + if (!file) + return NULL; + + if (theme) + f = XcursorScanTheme (theme, file); + if (!f) + f = XcursorScanTheme ("default", file); + if (f != NULL && f != XCURSOR_SCAN_CORE) + { + images = _XcursorFileLoadImages (f, size, resized); + if (images) + XcursorImagesSetName (images, file); + fclose (f); + } + return images; } XcursorImages * @@ -335,8 +366,11 @@ XcursorLibraryLoadImages (const char *file, const char *theme, int size) FILE *f = NULL; XcursorImages *images = NULL; + enterFunc((T_CALLED(XcursorLibraryLoadImages) "(\"%s\", \"%s\", %d)\n", + NonNull(file), NonNull(theme), size)); + if (!file) - return NULL; + returnAddr(NULL); if (theme) f = XcursorScanTheme (theme, file); @@ -349,48 +383,53 @@ XcursorLibraryLoadImages (const char *file, const char *theme, int size) XcursorImagesSetName (images, file); fclose (f); } - return images; + returnAddr(images); } Cursor XcursorLibraryLoadCursor (Display *dpy, const char *file) { - int size = XcursorGetDefaultSize (dpy); - char *theme = XcursorGetTheme (dpy); - XcursorImages *images = XcursorLibraryLoadImages (file, theme, size); - Cursor cursor; + XcursorImages *images; + Cursor cursor = 0; + + enterFunc((T_CALLED(XcursorLibraryLoadCursor) "(%p, \"%s\")\n", + (void*)dpy, NonNull(file))); if (!file) - return 0; + returnLong(cursor); + images = _XcursorLibraryLoadImages (dpy, file); if (!images) { int id = XcursorLibraryShape (file); if (id >= 0) - return _XcursorCreateFontCursor (dpy, (unsigned) id); - else - return 0; + cursor = _XcursorCreateFontCursor (dpy, (unsigned) id); } - cursor = XcursorImagesLoadCursor (dpy, images); - XcursorImagesDestroy (images); + else + { + cursor = XcursorImagesLoadCursor (dpy, images); + XcursorImagesDestroy (images); #if defined HAVE_XFIXES && XFIXES_MAJOR >= 2 - XFixesSetCursorName (dpy, cursor, file); + XFixesSetCursorName (dpy, cursor, file); #endif - return cursor; + } + returnLong(cursor); } XcursorCursors * XcursorLibraryLoadCursors (Display *dpy, const char *file) { - int size = XcursorGetDefaultSize (dpy); - char *theme = XcursorGetTheme (dpy); - XcursorImages *images = XcursorLibraryLoadImages (file, theme, size); + XcursorImages *images; XcursorCursors *cursors; + enterFunc((T_CALLED(XcursorLibraryLoadCursors) "(%p, \"%s\")\n", + (void*)dpy, NonNull(file))); + if (!file) - return NULL; + returnAddr(NULL); + images = _XcursorLibraryLoadImages (dpy, file); if (!images) { int id = XcursorLibraryShape (file); @@ -418,7 +457,7 @@ XcursorLibraryLoadCursors (Display *dpy, const char *file) cursors = XcursorImagesLoadCursors (dpy, images); XcursorImagesDestroy (images); } - return cursors; + returnAddr(cursors); } static const char _XcursorStandardNames[] = @@ -518,44 +557,75 @@ XcursorImage * XcursorShapeLoadImage (unsigned int shape, const char *theme, int size) { unsigned int id = shape >> 1; + XcursorImage *result = NULL; + + enterFunc((T_CALLED(XcursorShapeLoadImage) "(%u, \"%s\", %d)\n", + shape, NonNull(theme), size)); if (id < NUM_STANDARD_NAMES) - return XcursorLibraryLoadImage (STANDARD_NAME (id), theme, size); - else - return NULL; + result = XcursorLibraryLoadImage (STANDARD_NAME (id), theme, size); + + returnAddr(result); +} + +XcursorImages * +_XcursorShapeLoadImages (Display *dpy, unsigned int shape) +{ + unsigned int id = shape >> 1; + XcursorImages *result = NULL; + + enterFunc((T_CALLED(_XcursorShapeLoadImages) "(%p, %u)\n", + (void*)dpy, shape)); + + if (id < NUM_STANDARD_NAMES) + result = _XcursorLibraryLoadImages (dpy, STANDARD_NAME (id)); + + returnAddr(result); } XcursorImages * XcursorShapeLoadImages (unsigned int shape, const char *theme, int size) { unsigned int id = shape >> 1; + XcursorImages *result = NULL; + + enterFunc((T_CALLED(XcursorShapeLoadImages) "(%u, \"%s\", %d)\n", + shape, NonNull(theme), size)); if (id < NUM_STANDARD_NAMES) - return XcursorLibraryLoadImages (STANDARD_NAME (id), theme, size); - else - return NULL; + result = XcursorLibraryLoadImages (STANDARD_NAME (id), theme, size); + + returnAddr(result); } Cursor XcursorShapeLoadCursor (Display *dpy, unsigned int shape) { unsigned int id = shape >> 1; + Cursor result = None; + + enterFunc((T_CALLED(XcursorShapeLoadCursor) "(%p, %u)\n", + (void*)dpy, shape)); if (id < NUM_STANDARD_NAMES) - return XcursorLibraryLoadCursor (dpy, STANDARD_NAME (id)); - else - return 0; + result = XcursorLibraryLoadCursor (dpy, STANDARD_NAME (id)); + + returnLong(result); } XcursorCursors * XcursorShapeLoadCursors (Display *dpy, unsigned int shape) { unsigned int id = shape >> 1; + XcursorCursors *result = NULL; + + enterFunc((T_CALLED(XcursorShapeLoadCursors) "(%p, %u)\n", + (void*)dpy, shape)); if (id < NUM_STANDARD_NAMES) - return XcursorLibraryLoadCursors (dpy, STANDARD_NAME (id)); - else - return NULL; + result = XcursorLibraryLoadCursors (dpy, STANDARD_NAME (id)); + + returnAddr(result); } int @@ -563,6 +633,8 @@ XcursorLibraryShape (const char *library) { int low, high; + enterFunc((T_CALLED(XcursorLibraryShape) "(%s)\n", NonNull(library))); + low = 0; high = NUM_STANDARD_NAMES - 1; while (low < high - 1) @@ -570,7 +642,7 @@ XcursorLibraryShape (const char *library) int mid = (low + high) >> 1; int c = strcmp (library, STANDARD_NAME (mid)); if (c == 0) - return (mid << 1); + returnCode(mid << 1); if (c > 0) low = mid; else @@ -582,5 +654,5 @@ XcursorLibraryShape (const char *library) return (low << 1); low++; } - return -1; + returnCode(-1); } diff --git a/lib/libXcursor/src/xcursorint.h b/lib/libXcursor/src/xcursorint.h index ebc8ee60d..5fca76efb 100644 --- a/lib/libXcursor/src/xcursorint.h +++ b/lib/libXcursor/src/xcursorint.h @@ -1,4 +1,5 @@ /* + * Copyright © 2024 Thomas E. Dickey * Copyright © 2002 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its @@ -86,6 +87,7 @@ typedef struct _XcursorDisplayInfo { XExtCodes *codes; XcursorBool has_render_cursor; XcursorBool has_anim_cursor; + XcursorBool resized_cursors; XcursorBool theme_core; int size; XcursorFontInfo *fonts; @@ -110,4 +112,49 @@ _XcursorCreateGlyphCursor(Display *dpy, Cursor _XcursorCreateFontCursor (Display *dpy, unsigned int shape); +/* provide for XCURSOR_RESIZED */ +XcursorImage * +_XcursorFileLoadImage (FILE *file, int size, XcursorBool resize); + +XcursorImages * +_XcursorXcFileLoadImages (XcursorFile *file, int size, XcursorBool resize); + +XcursorImages * +_XcursorFileLoadImages (FILE *file, int size, XcursorBool resize); + +XcursorImages * +_XcursorFilenameLoadImages (const char *file, int size, XcursorBool resize); + +XcursorImages * +_XcursorShapeLoadImages (Display *dpy, unsigned int shape); + +#ifdef DEBUG_XCURSOR +void _XcursorTrace(const char *fmt, ...) __attribute__((format(printf,1,2))); +void *_XcursorReturnAddr(void *addr); +int _XcursorReturnCode(int code); +unsigned long _XcursorReturnLong(unsigned long code); +unsigned _XcursorReturnUint(unsigned code); +void _XcursorReturnVoid(void); +#define T_CALLED(func) "called: { " #func +#define T_OPTION(opts) "option: : " #opts +#define T_RETURN(form) "return: } %" #form "\n" +#define enterFunc(params) _XcursorTrace params +#define traceOpts(params) _XcursorTrace params +#define returnAddr(addr) return _XcursorReturnAddr(addr) +#define returnCode(code) return _XcursorReturnCode(code) +#define returnLong(code) return _XcursorReturnLong(code) +#define returnUint(code) return _XcursorReturnUint(code) +#define returnVoid() do { _XcursorReturnVoid(); return; } while (0) +#else +#define enterFunc(params) /* nothing */ +#define traceOpts(params) /* nothing */ +#define returnAddr(addr) return (addr) +#define returnCode(code) return (code) +#define returnLong(code) return (code) +#define returnUint(code) return (code) +#define returnVoid() return +#endif + +#define NonNull(p) ((p) != NULL ? (p) : "") + #endif /* _XCURSORINT_H_ */ diff --git a/lib/libXcursor/src/xlib.c b/lib/libXcursor/src/xlib.c index 63f0225fe..79a31f310 100644 --- a/lib/libXcursor/src/xlib.c +++ b/lib/libXcursor/src/xlib.c @@ -1,4 +1,5 @@ /* + * Copyright © 2024 Thomas E. Dickey * Copyright © 2002 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its @@ -90,19 +91,23 @@ XcursorTryShapeCursor (Display *dpy, { Cursor cursor = None; + enterFunc((T_CALLED(XcursorTryShapeCursor) "(%p, %lu, %lu, %u, %u, %p, %p)\n", + (void*)dpy, source_font, mask_font, + source_char, mask_char, + (const void*)foreground, + (const void*)background)); + if (!dpy || !source_font || !mask_font || !foreground || !background) - return 0; + returnLong(None); if (!XcursorSupportsARGB (dpy) && !XcursorGetThemeCore (dpy)) - return None; + returnLong(None); if (source_font == mask_font && _XcursorFontIsCursor (dpy, source_font) && source_char + 1 == mask_char) { - int size = XcursorGetDefaultSize (dpy); - char *theme = XcursorGetTheme (dpy); - XcursorImages *images = XcursorShapeLoadImages (source_char, theme, size); + XcursorImages *images = _XcursorShapeLoadImages (dpy, source_char); if (images) { @@ -110,7 +115,7 @@ XcursorTryShapeCursor (Display *dpy, XcursorImagesDestroy (images); } } - return cursor; + returnLong(cursor); } void @@ -126,18 +131,21 @@ XcursorNoticeCreateBitmap (Display *dpy, int replace = 0; XcursorBitmapInfo *bmi; + enterFunc((T_CALLED(XcursorNoticeCreateBitmap) "(%p, %lu, %u, %u)\n", + (void*)dpy, pid, width, height)); + if (!dpy) - return; + returnVoid(); if (!XcursorSupportsARGB (dpy) && !XcursorGetThemeCore (dpy)) - return; + returnVoid(); if (width > MAX_BITMAP_CURSOR_SIZE || height > MAX_BITMAP_CURSOR_SIZE) - return; + returnVoid(); info = _XcursorGetDisplayInfo (dpy); if (!info) - return; + returnVoid(); LockDisplay (dpy); replace = 0; @@ -164,6 +172,8 @@ XcursorNoticeCreateBitmap (Display *dpy, bmi->height = height; bmi->has_image = False; UnlockDisplay (dpy); + + returnVoid(); } static XcursorBitmapInfo * @@ -247,8 +257,11 @@ XcursorImageHash (XImage *image, int low_addr; Bool bit_swap; + enterFunc((T_CALLED(XcursorImageHash) "(%p, %p)\n", + (void*)image, (void*)hash)); + if (!image) - return; + returnVoid(); for (i = 0; i < XCURSOR_BITMAP_HASH_SIZE; i++) hash[i] = 0; @@ -295,6 +308,8 @@ XcursorImageHash (XImage *image, } line += image->bytes_per_line; } + + returnVoid(); } static Bool @@ -309,6 +324,7 @@ _XcursorLogDiscover (void) if (getenv ("XCURSOR_DISCOVER")) log = True; + traceOpts((T_OPTION(XCURSOR_DISCOVER) ": %d\n", log)); } return log; } @@ -320,26 +336,29 @@ XcursorNoticePutBitmap (Display *dpy, { XcursorBitmapInfo *bmi; + enterFunc((T_CALLED(XcursorNoticePutBitmap ) "(%p, %lu, %p)\n", + (void*)dpy, draw, (void*)image)); + if (!dpy || !image) - return; + returnVoid(); if (!XcursorSupportsARGB (dpy) && !XcursorGetThemeCore (dpy)) - return; + returnVoid(); if (image->width > MAX_BITMAP_CURSOR_SIZE || image->height > MAX_BITMAP_CURSOR_SIZE) - return; + returnVoid(); bmi = _XcursorGetBitmap (dpy, (Pixmap) draw); if (!bmi) - return; + returnVoid(); /* * Make sure the image fills the bitmap */ if (image->width != (int)bmi->width || image->height != (int)bmi->height) { bmi->bitmap = 0; - return; + returnVoid(); } /* * If multiple images are placed in the same bitmap, @@ -348,7 +367,7 @@ XcursorNoticePutBitmap (Display *dpy, if (bmi->has_image) { bmi->bitmap = 0; - return; + returnVoid(); } /* * Make sure the image is valid @@ -356,7 +375,7 @@ XcursorNoticePutBitmap (Display *dpy, if (image->bytes_per_line & ((image->bitmap_unit >> 3) - 1)) { bmi->bitmap = 0; - return; + returnVoid(); } /* * Hash the image @@ -387,6 +406,7 @@ XcursorNoticePutBitmap (Display *dpy, } } bmi->has_image = True; + returnVoid(); } Cursor @@ -407,19 +427,27 @@ XcursorTryShapeBitmapCursor (Display *dpy, (void) x; /* UNUSED */ (void) y; /* UNUSED */ + enterFunc((T_CALLED(XcursorTryShapeBitmapCursor) + "(%p, %lu, %lu, %p, %p, %u, %u)\n", + (void*)dpy, + source, mask, + (void*)foreground, + (void*)background, + x, y)); + if (!dpy || !foreground || !background) - return 0; + returnLong(None); if (!XcursorSupportsARGB (dpy) && !XcursorGetThemeCore (dpy)) - return None; + returnLong(None); bmi = _XcursorGetBitmap (dpy, source); if (!bmi || !bmi->has_image) - return None; + returnLong(None); for (i = 0; i < XCURSOR_BITMAP_HASH_SIZE; i++) sprintf (name + 2 * i, "%02x", bmi->hash[i]); cursor = XcursorLibraryLoadCursor (dpy, name); if (_XcursorLogDiscover()) printf ("Cursor hash %s returns 0x%x\n", name, (unsigned int) cursor); - return cursor; + returnLong(cursor); } -- cgit v1.2.3