git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@5139 3789f03b-4d11-0410-bbf8-ca57d06f2519tags/v1.3.90
@@ -138,6 +138,8 @@ apply_patch 2816 fltk-1_v3.3.0-icons.patch | |||
apply_patch 2860 fltk-1.3.x-screen_num.patch | |||
apply_patch 2860 fltk-1_v3.3.x-multihead.patch | |||
### END SCRIPT ### | |||
3. Use CMake to build FLTK using the same procedures described below for | |||
building TigerVNC. The recipes in the "Build Recipes" section also apply. | |||
If you want optimized code, make sure to build with | |||
@@ -662,3 +664,35 @@ MinGW Build on Linux | |||
-DCMAKE_RANLIB={mingw_binary_path}/i386-mingw32-ranlib \ | |||
{source_directory} | |||
make | |||
=============================== | |||
Distribution-Specific Packaging | |||
=============================== | |||
RPM Packages for RHEL / CentOS | |||
------------------------------ | |||
The RPM spec files and patches used to create the nightly builds | |||
and releases can be found in the "contrib/rpm/el{5,6}" directories | |||
of the TigerVNC subversion trunk. All external source tarballs | |||
must be fetched manually and placed into the 'SOURCES' directory | |||
under the rpmbuild root. Additonally, the following macros need | |||
to be defined: | |||
EL6: | |||
%debug_package %{nil} | |||
EL5: | |||
%dist .el5 | |||
%_smp_mflags -j3 | |||
%debug_package %{nil} | |||
%__arch_install_post /usr/lib/rpm/check-rpaths /usr/lib/rpm/check-buildroot | |||
Debian packages for Ubuntu 12.04LTS | |||
----------------------------------- | |||
The debian folder used to create the nightly builds and releases | |||
can be found in the "contrib/deb/ubuntu-precise" directory of the | |||
TigerVNC subversion trunk. |
@@ -0,0 +1,31 @@ | |||
tigervnc (1.3.0-3ubuntu1) precise; urgency=low | |||
* Build Xvnc against native upstream xorg sources, using native config | |||
options. Use distro-specific fltk1.3 sources. | |||
-- Brian P. Hinz <bphinz@users.sourceforge.net> Sun, 14 Jul 2013 15:22:28 -0400 | |||
tigervnc (1.3.0-3) precise; urgency=low | |||
* Additional dependencies (derived from ldd | dpkg -S). | |||
-- Brian P. Hinz <bphinz@users.sourceforge.net> Sun, 07 Jul 2013 11:01:33 -0400 | |||
tigervnc (1.3.0-2) precise; urgency=low | |||
* Added build dependencies to improve font support in viewer. | |||
-- Brian P. Hinz <bphinz@users.sourceforge.net> Sun, 07 Jul 2013 10:44:05 -0400 | |||
tigervnc (1.3.0-1) precise; urgency=low | |||
* Removed java viewer from server package. Fixed typo in server | |||
dependencies. | |||
-- Brian P. Hinz <bphinz@users.sourceforge.net> Sun, 07 Jul 2013 09:55:44 -0400 | |||
tigervnc (1.3.0) precise; urgency=low | |||
* Initial release. | |||
-- Brian P. Hinz <bphinz@users.sourceforge.net> Fri, 05 Jul 2013 00:47:02 -0400 |
@@ -0,0 +1 @@ | |||
9 |
@@ -0,0 +1,70 @@ | |||
Source: tigervnc | |||
Section: x11 | |||
Priority: optional | |||
Maintainer: Brian P. Hinz <bphinz@users.sourceforge.net> | |||
Standards-Version: 3.8.4 | |||
Build-Depends: debhelper (>> 7.1), zlib1g-dev, libjpeg-turbo8-dev, libxaw7-dev (>> 4.1.0), perl-modules, xfonts-base, xutils-dev, libx11-dev, libxau-dev, libxext-dev, libxi-dev, libxkbfile-dev, libxmu-dev, libxt-dev, x11proto-core-dev, cmake (>> 2.8), libgnutls-dev, libpam0g-dev, libpng-dev, automake, autoconf, libtool, pkg-config, libpixman-1-dev, x11proto-bigreqs-dev, x11proto-composite-dev, x11proto-damage-dev, x11proto-dri2-dev, x11proto-fixes-dev, x11proto-fonts-dev, x11proto-gl-dev, x11proto-input-dev, x11proto-kb-dev, x11proto-randr-dev, x11proto-render-dev, x11proto-resource-dev, x11proto-scrnsaver-dev, x11proto-video-dev, x11proto-xcmisc-dev, x11proto-xext-dev, x11proto-xf86bigfont-dev, x11proto-xf86dga-dev, x11proto-xf86dri-dev, x11proto-xf86misc-dev, x11proto-xf86vidmode-dev, x11proto-xinerama-dev, libosmesa6-dev, libgl1-mesa-dev, libgl1-mesa-dri, libgl1-mesa-glx, libxfont-dev, x11proto-record-dev, default-jdk, libxtst-dev, libxft-dev, libexpat1-dev, libfontconfig1-dev, libxrender-dev, libt1-dev, libpciaccess-dev, curl, bzip2, quilt | |||
Homepage: http://www.tigervnc.com | |||
Package: tigervncserver | |||
Architecture: amd64 i386 | |||
Provides: xserver, vnc-server | |||
Depends: x11-common | xserver-common, x11-utils, xauth, libbz2-1.0, libc6, libfontenc1, libfreetype6, libgcc1, libgcrypt11, libgl1-mesa-dri, libgnutls26, libgpg-error0, libjpeg-turbo8, libp11-kit0, libpam0g, libpixman-1-0, libstdc++6, libtasn1-3, libx11-6, libxau6, libxcb1, libxdmcp6, libxext6, libxfont1, libxtst6, zlib1g | |||
Recommends: xfonts-base, x11-xserver-utils | |||
Suggests: xtigervncviewer, tigervnc-java | |||
Description: virtual network computing server software | |||
Virtual Network Computing (VNC) is a remote display system which allows you to | |||
view and interact with a virtual desktop environment that is running on another | |||
computer on the network. Using VNC, you can run graphical applications on a | |||
remote machine and send only the display from these applications to your local | |||
machine. VNC is platform-independent and supports a wide variety of operating | |||
systems and architectures as both servers and clients. | |||
. | |||
TigerVNC is a high-speed version of VNC based on the RealVNC 4 and X.org code | |||
bases. TigerVNC started as a next-generation development effort for TightVNC | |||
on Unix and Linux platforms, but it split from its parent project in early 2009 | |||
so that TightVNC could focus on Windows platforms. TigerVNC supports a variant | |||
of Tight encoding that is greatly accelerated by the use of the libjpeg-turbo | |||
JPEG codec. | |||
Package: xtigervncviewer | |||
Architecture: amd64 i386 | |||
Provides: vncviewer, vnc-viewer | |||
Depends: libc6, libexpat1, libfontconfig1, libfreetype6, libgcc1, libgcrypt11, libgnutls26, libgpg-error0, libjpeg-turbo8, libp11-kit0, libpng12-0, libstdc++6, libtasn1-3, libx11-6, libxau6, libxcb1, libxdmcp6, libxext6, libxft2, libxrender1, zlib1g | |||
Recommends: xfonts-base | |||
Suggests: tigervncserver, ssh | |||
Description: virtual network computing client software for X | |||
Virtual Network Computing (VNC) is a remote display system which allows you to | |||
view and interact with a virtual desktop environment that is running on another | |||
computer on the network. Using VNC, you can run graphical applications on a | |||
remote machine and send only the display from these applications to your local | |||
machine. VNC is platform-independent and supports a wide variety of operating | |||
systems and architectures as both servers and clients. | |||
. | |||
TigerVNC is a high-speed version of VNC based on the RealVNC 4 and X.org code | |||
bases. TigerVNC started as a next-generation development effort for TightVNC | |||
on Unix and Linux platforms, but it split from its parent project in early 2009 | |||
so that TightVNC could focus on Windows platforms. TigerVNC supports a variant | |||
of Tight encoding that is greatly accelerated by the use of the libjpeg-turbo | |||
JPEG codec. | |||
Package: tigervnc-java | |||
Architecture: any | |||
Suggests: tigervncserver | |||
Provides: vncviewer, vnc-viewer | |||
Depends: default-jre | |||
Description: TigerVNC java applet | |||
Virtual Network Computing (VNC) is a remote display system which allows you to | |||
view and interact with a virtual desktop environment that is running on another | |||
computer on the network. Using VNC, you can run graphical applications on a | |||
remote machine and send only the display from these applications to your local | |||
machine. VNC is platform-independent and supports a wide variety of operating | |||
systems and architectures as both servers and clients. | |||
. | |||
TigerVNC is a high-speed version of VNC based on the RealVNC 4 and X.org code | |||
bases. TigerVNC started as a next-generation development effort for TightVNC | |||
on Unix and Linux platforms, but it split from its parent project in early 2009 | |||
so that TightVNC could focus on Windows platforms. TigerVNC supports a variant | |||
of Tight encoding that is greatly accelerated by the use of the libjpeg-turbo | |||
JPEG codec. | |||
@@ -0,0 +1,116 @@ | |||
This package was packaged for Debian by Brian P. Hinz <bphinz@users.sourceforge.net> | |||
on Tue, 02 Jul 2013 21:33:24 +0500 using the tightvnc package as a base. | |||
It was downloaded from: | |||
http://www.tigervnc.org/ | |||
COPYRIGHT: | |||
========== | |||
TigerVNC is | |||
Copyright (C) 1999 AT&T Laboratories Cambridge | |||
Copyright (C) 2002-2005 RealVNC Ltd. | |||
Copyright (C) 2000-2006 TightVNC Group | |||
Copyright (C) 2005-2006 Martin Koegler | |||
Copyright (C) 2005-2006 Sun Microsystems, Inc. | |||
Copyright (C) 2006 OCCAM Financial Technology | |||
Copyright (C) 2000-2008 Constantin Kaplinsky | |||
Copyright (C) 2004-2009 Peter Astrand for Cendio AB | |||
Copyright (C) 2010 Antoine Martin | |||
Copyright (C) 2010 m-privacy GmbH | |||
Copyright (C) 2009-2011 D. R. Commander | |||
Copyright (C) 2009-2011 Pierre Ossman for Cendio AB | |||
Copyright (C) 2004, 2009-2011 Red Hat, Inc. | |||
Copyright (C) 2009-2011 TigerVNC Team | |||
All Rights Reserved. | |||
This software is distributed under the GNU General Public Licence as published | |||
by the Free Software Foundation. See the file LICENCE.TXT for the conditions | |||
under which this software is made available. TigerVNC also contains code from | |||
other sources. See the Acknowledgements section below, and the individual | |||
source files, for details of the conditions under which they are made | |||
available. | |||
ACKNOWLEDGEMENTS | |||
================ | |||
This distribution contains zlib compression software. This is: | |||
Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler | |||
This software is provided 'as-is', without any express or implied | |||
warranty. In no event will the authors be held liable for any damages | |||
arising from the use of this software. | |||
Permission is granted to anyone to use this software for any purpose, | |||
including commercial applications, and to alter it and redistribute it | |||
freely, subject to the following restrictions: | |||
1. The origin of this software must not be misrepresented; you must not | |||
claim that you wrote the original software. If you use this software | |||
in a product, an acknowledgment in the product documentation would be | |||
appreciated but is not required. | |||
2. Altered source versions must be plainly marked as such, and must not be | |||
misrepresented as being the original software. | |||
3. This notice may not be removed or altered from any source distribution. | |||
Jean-loup Gailly Mark Adler | |||
jloup@gzip.org madler@alumni.caltech.edu | |||
The data format used by the zlib library is described by RFCs (Request for | |||
Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt | |||
(zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). | |||
This distribution contains public domain DES software by Richard Outerbridge. | |||
This is: | |||
Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge. | |||
(GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992. | |||
This distribution contains software from the X Window System. This is: | |||
Copyright 1987, 1988, 1998 The Open Group | |||
Permission to use, copy, modify, distribute, and sell this software and its | |||
documentation for any purpose is hereby granted without fee, provided that | |||
the above copyright notice appear in all copies and that both that | |||
copyright notice and this permission notice appear in supporting | |||
documentation. | |||
The above copyright notice and this permission notice shall be included in | |||
all copies or substantial portions of the Software. | |||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN | |||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
Except as contained in this notice, the name of The Open Group shall not be | |||
used in advertising or otherwise to promote the sale, use or other dealings | |||
in this Software without prior written authorization from The Open Group. | |||
Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. | |||
All Rights Reserved | |||
Permission to use, copy, modify, and distribute this software and its | |||
documentation for any purpose and without fee is hereby granted, | |||
provided that the above copyright notice appear in all copies and that | |||
both that copyright notice and this permission notice appear in | |||
supporting documentation, and that the name of Digital not be | |||
used in advertising or publicity pertaining to distribution of the | |||
software without specific, written prior permission. | |||
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING | |||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL | |||
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR | |||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, | |||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | |||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | |||
SOFTWARE. |
@@ -0,0 +1,38 @@ | |||
#!/bin/bash | |||
#curl -L -o tigervnc-1.3.0.tar.bz2 "http://downloads.sourceforge.net/project/tigervnc/tigervnc/1.3.0/tigervnc-1.3.0.tar.bz2" | |||
#tar xjf tigervnc-*.tar.bz2 | |||
#rm tigervnc-*.tar.bz2 | |||
curl -OL http://sourceforge.net/code-snapshots/svn/t/ti/tigervnc/code/tigervnc-code-5136-trunk.zip | |||
unzip tigervnc-code-*-trunk.zip | |||
mv tigervnc-code-*-trunk tigervnc-1.3.80 | |||
rm tigervnc-code-*-trunk.zip | |||
pushd tigervnc-* | |||
curl -L -o fltk-1.3.2-source.tar.gz 'http://anonscm.debian.org/gitweb/?p=users/ucko/fltk1.3.git;a=snapshot;h=HEAD;sf=tgz' | |||
tar xzf fltk-*-source.tar.gz | |||
rm fltk-*-source.tar.gz | |||
mv fltk1.3-* fltk-1.3.2 | |||
pushd fltk-* | |||
sh ../../debian/patch_fltk.sh | |||
find . -name "*.orig" -exec rm {} \; | |||
popd | |||
curl -L -o xorg-server-1.11.4-0ubuntu10.3.tar.gz 'http://anonscm.debian.org/gitweb/?p=pkg-xorg/xserver/xorg-server.git;a=snapshot;h=cbf435a091906484112f5c4cf35b17738e779ce9;sf=tgz' | |||
tar xzf xorg-server-*.tar.gz | |||
rm xorg-server-*.tar.gz | |||
pushd xorg-server-* | |||
QUILT_PATCHES=debian/patches quilt push -a | |||
popd | |||
cp -r xorg-server-*/* unix/xserver | |||
rm -rf xorg-server-* | |||
pushd unix/xserver | |||
for all in `find . -type f -perm -001`; do | |||
chmod -x "$all" | |||
done | |||
patch -p1 -b --suffix .vnc < ../xserver111.patch | |||
popd | |||
popd | |||
if [ -e tigervnc_1.3.80.orig.tar.gz ] ; then | |||
rm tigervnc_1.3.80.orig.tar.gz | |||
fi | |||
tar czf tigervnc_1.3.80.orig.tar.gz tigervnc-1.3.80 | |||
rm -rf tigervnc-1.3.80 |
@@ -0,0 +1,111 @@ | |||
#!/bin/bash | |||
# Scripted by Maxim Heijndijk | |||
# chkconfig: 2345 91 35 | |||
# description: Starts and stops vncserver. \ | |||
# Used to provide remote X administration services. | |||
### BEGIN INIT INFO | |||
# Provides: vncservers | |||
# Default-Start: 2 3 4 5 | |||
# Default-Stop: 0 1 6 | |||
# Required-Start: networking | |||
# Required-Stop: networking | |||
# Short-Description: Starts and stops vncserver | |||
# Description: Used to provide remote X administration services. | |||
### END INIT INFO | |||
# Source function library. | |||
. /lib/lsb/init-functions | |||
VNCSERVERS="" | |||
[ -f /etc/default/vncservers ] && . /etc/default/vncservers || exit 0 | |||
start() { | |||
ulimit -S -c 0 >/dev/null 2>&1 | |||
RETVAL=0 | |||
for display in ${VNCSERVERS}; do | |||
eval cd ~${display##*:} | |||
if [ -e ".vnc/passwd" ]; then | |||
log_begin_msg "Starting VNC Server for user ${display##*:}:" | |||
unset BASH_ENV ENV | |||
su ${display##*:} -c "cd ~${display##*:} && vncserver :${display%%:*}" | |||
RETVAL="$?" | |||
if [ "$RETVAL" -ne 0 ]; then | |||
log_end_msg 1 | |||
break | |||
else | |||
log_end_msg 0 | |||
fi | |||
else | |||
log_begin_msg "Not starting VNC Server for user ${display##*:}.\n File \"~${display##*:}/.vnc/passwd\" not found.\n Create a password file for the VNC server with vncpasswd" | |||
log_end_msg 1 | |||
fi | |||
done | |||
[ "$RETVAL" -eq 0 ] && touch "/var/lock/vncserver" | |||
} | |||
stop() { | |||
unset BASH_ENV ENV | |||
for display in ${VNCSERVERS}; do | |||
log_begin_msg "Shutting down VNC Server for user ${display##*:}: " | |||
su ${display##*:} -c "vncserver -kill :${display%%:*}" >/dev/null 2>&1 | |||
RETVAL="$?" | |||
[ "$RETVAL" -eq 0 ] && log_end_msg 0 || log_end_msg 1 | |||
done | |||
[ -f "/var/lock/vncserver" ] && rm -f "/var/lock/vncserver" | |||
} | |||
case "$1" in | |||
start) start | |||
;; | |||
stop) stop | |||
;; | |||
restart|reload) stop | |||
start | |||
;; | |||
*) echo $"Usage: $0 {start|stop|restart}" | |||
exit 1 | |||
;; | |||
esac | |||
exit 0 |
@@ -0,0 +1,19 @@ | |||
# The VNCSERVERS variable is a list of display:user pairs. | |||
# | |||
# Uncomment the lines below to start a VNC server on display :2 | |||
# as my 'myusername' (adjust this to your own). You will also | |||
# need to set a VNC password; run 'man vncpasswd' to see how | |||
# to do that. | |||
# | |||
# DO NOT RUN THIS SERVICE if your local area network is | |||
# untrusted! For a secure way of using VNC, see this URL: | |||
# http://kbase.redhat.com/faq/docs/DOC-7028 | |||
# Use "-nolisten tcp" to prevent X connections to your VNC server via TCP. | |||
# Use "-localhost" to prevent remote VNC clients connecting except when | |||
# doing so through a secure tunnel. See the "-via" option in the | |||
# `man vncviewer' manual page. | |||
# VNCSERVERS="2:myusername" | |||
# VNCSERVERARGS[2]="-geometry 800x600 -nolisten tcp -localhost" |
@@ -0,0 +1,52 @@ | |||
#!/bin/bash | |||
set -e | |||
apply_patch() | |||
{ | |||
rm -f $2 | |||
curl -OL http://www.fltk.org/strfiles/$1/$2 | |||
patch -p1 < $2 | |||
} | |||
# Export dead key information from FLTK to the apps | |||
# http://www.fltk.org/str.php?L2599 | |||
apply_patch 2599 fltk-1_v4.3.x-keyboard-x11.patch | |||
apply_patch 2599 fltk-1_v4.3.x-keyboard-win32.patch | |||
apply_patch 2599 fltk-1_v6.3.x-keyboard-osx.patch | |||
# Notify applications of changes to the clipboard | |||
# http://www.fltk.org/str.php?L2636 | |||
apply_patch 2636 fltk-1.3.x-clipboard.patch | |||
apply_patch 2636 fltk-1_v6.3.x-clipboard-x11.patch | |||
apply_patch 2636 fltk-1_v3.3.x-clipboard-win32-fix.patch | |||
apply_patch 2636 fltk-1_v2.3.x-clipboard-win32.patch | |||
apply_patch 2636 fltk-1_v2.3.x-clipboard-osx.patch | |||
# Ability to convert a Fl_Pixmap to a Fl_RGB_Image | |||
# http://www.fltk.org/str.php?L2659 | |||
apply_patch 2659 pixmap_v2.patch | |||
# Support for custom cursors | |||
# http://www.fltk.org/str.php?L2660 | |||
apply_patch 2660 fltk-1_v5.3.x-cursor.patch | |||
# Improve modality interaction with WM | |||
# http://www.fltk.org/str.php?L2802 | |||
apply_patch 2802 fltk-1_v2.3.0-modal.patch | |||
# Window icons | |||
# http://www.fltk.org/str.php?L2816 | |||
apply_patch 2816 fltk-1_v3.3.0-icons.patch | |||
# Multihead | |||
# http://fltk.org/str.php?L2860 | |||
apply_patch 2860 fltk-1.3.x-screen_num.patch | |||
apply_patch 2860 fltk-1_v3.3.x-multihead.patch | |||
# Apply DRC's patches to FLTK | |||
curl -L 'https://sourceforge.net/mailarchive/attachment.php?list_name=tigervnc-devel&message_id=512DD1FE.7090609%40users.sourceforge.net&counter=1' -o 0001-Add-BUILD_STATIC-feature-from-TigerVNC-to-optionally.patch | |||
curl -L 'https://sourceforge.net/mailarchive/attachment.php?list_name=tigervnc-devel&message_id=512DD1FE.7090609%40users.sourceforge.net&counter=2' -o 0002-Fl_cocoa.mm-depends-on-some-Carbon-functions-so-we-n.patch | |||
curl -L 'https://sourceforge.net/mailarchive/attachment.php?list_name=tigervnc-devel&message_id=512DD1FE.7090609%40users.sourceforge.net&counter=3' -o 0003-We-need-to-unset-CMAKE_REQUIRED_LIBRARIES-after-chec.patch | |||
patch -p1 -i 0001-Add-BUILD_STATIC-feature-from-TigerVNC-to-optionally.patch | |||
patch -p1 -i 0002-Fl_cocoa.mm-depends-on-some-Carbon-functions-so-we-n.patch | |||
patch -p1 -i 0003-We-need-to-unset-CMAKE_REQUIRED_LIBRARIES-after-chec.patch |
@@ -0,0 +1,26 @@ | |||
--- a/unix/xserver/hw/vnc/xvnc.cc 2013-07-14 14:05:29.963390223 -0400 | |||
+++ b/unix/xserver/hw/vnc/xvnc.cc 2013-07-14 14:04:12.840357191 -0400 | |||
@@ -250,7 +250,7 @@ | |||
#if XORG < 111 | |||
AbortDDX() | |||
#else | |||
-AbortDDX(enum ExitCode error) | |||
+SigAbortDDX(int signo, enum ExitCode error) | |||
#endif | |||
{ | |||
#if XORG < 111 | |||
@@ -260,6 +260,14 @@ | |||
#endif | |||
} | |||
+#if XORG >= 111 | |||
+void | |||
+AbortDDX(enum ExitCode error) | |||
+{ | |||
+ SigAbortDDX(0, error); | |||
+} | |||
+#endif | |||
+ | |||
#ifdef __DARWIN__ | |||
void | |||
DarwinHandleGUI(int argc, char *argv[]) |
@@ -0,0 +1,36 @@ | |||
--- a/unix/vncserver 2009-11-12 11:39:54.000000000 +0100 | |||
+++ b/unix/vncserver 2009-12-21 16:15:01.907799091 +0100 | |||
@@ -189,27 +189,12 @@ $vncPort = 5900 + $displayNumber; | |||
$desktopLog = "$vncUserDir/$host:$displayNumber.log"; | |||
unlink($desktopLog); | |||
-# Make an X server cookie - use /dev/urandom on systems that have it, | |||
-# otherwise use perl's random number generator, seeded with the sum | |||
-# of the current time, our PID and part of the encrypted form of the password. | |||
- | |||
-my $cookie = ""; | |||
-if (open(URANDOM, '<', '/dev/urandom')) { | |||
- my $randata; | |||
- if (sysread(URANDOM, $randata, 16) == 16) { | |||
- $cookie = unpack 'h*', $randata; | |||
- } | |||
- close(URANDOM); | |||
-} | |||
-if ($cookie eq "") { | |||
- srand(time+$$+unpack("L",`cat $vncUserDir/passwd`)); | |||
- for (1..16) { | |||
- $cookie .= sprintf("%02x", int(rand(256)) % 256); | |||
- } | |||
-} | |||
- | |||
-system("xauth -f $xauthorityFile add $host:$displayNumber . $cookie"); | |||
-system("xauth -f $xauthorityFile add $host/unix:$displayNumber . $cookie"); | |||
+# Make an X server cookie - use mcookie | |||
+$cookie = `/usr/bin/mcookie`; | |||
+open (XAUTH, "|xauth -f $xauthorityFile source -"); | |||
+print XAUTH "add $host:$displayNumber . $cookie\n"; | |||
+print XAUTH "add $host/unix:$displayNumber . $cookie\n"; | |||
+close XAUTH; | |||
if ($opt{'-name'}) { | |||
$desktopName = $opt{'-name'}; |
@@ -0,0 +1,11 @@ | |||
--- a/unix/xserver/hw/vnc/Makefile.am 2011-10-31 09:14:40.000000000 +0100 | |||
+++ b/unix/xserver/hw/vnc/Makefile.am 2012-08-22 15:51:47.013241342 +0200 | |||
@@ -53,7 +53,7 @@ libvnc_la_CPPFLAGS = $(XVNC_CPPFLAGS) -I | |||
-I$(top_srcdir)/include \ | |||
${XSERVERLIBS_CFLAGS} -I$(includedir) | |||
-libvnc_la_LDFLAGS = -module -avoid-version | |||
+libvnc_la_LDFLAGS = -module -avoid-version -Wl,-z,now | |||
libvnc_la_LIBADD = libvnccommon.la $(COMMON_LIBS) | |||
@@ -0,0 +1,19 @@ | |||
--- a/unix/xserver/hw/vnc/Makefile.am 2012-08-22 15:52:01.876216608 +0200 | |||
+++ b/unix/xserver/hw/vnc/Makefile.am 2012-08-22 15:52:45.973143684 +0200 | |||
@@ -5,6 +5,7 @@ RFB_LIB=$(LIB_DIR)/rfb/librfb.la | |||
RDR_LIB=$(LIB_DIR)/rdr/librdr.la | |||
NETWORK_LIB=$(LIB_DIR)/network/libnetwork.la | |||
XREGION_LIB=$(LIB_DIR)/Xregion/libXregion.la | |||
+OS_LIB=$(LIB_DIR)/os/libos.la | |||
COMMON_LIBS=$(NETWORK_LIB) $(RFB_LIB) $(RDR_LIB) $(XREGION_LIB) | |||
noinst_LTLIBRARIES = libvnccommon.la | |||
@@ -55,7 +56,7 @@ libvnc_la_CPPFLAGS = $(XVNC_CPPFLAGS) -I | |||
libvnc_la_LDFLAGS = -module -avoid-version -Wl,-z,now | |||
-libvnc_la_LIBADD = libvnccommon.la $(COMMON_LIBS) | |||
+libvnc_la_LIBADD = libvnccommon.la $(COMMON_LIBS) $(OS_LIB) | |||
EXTRA_DIST = Xvnc.man | |||
@@ -0,0 +1,43 @@ | |||
--- a/common/rfb/SecurityClient.cxx 2011-02-21 14:14:16.000000000 +0100 | |||
+++ b/common/rfb/SecurityClient.cxx 2011-03-31 09:47:34.519099718 +0200 | |||
@@ -45,7 +45,7 @@ StringParameter SecurityClient::secTypes | |||
("SecurityTypes", | |||
"Specify which security scheme to use (None, VncAuth)", | |||
#ifdef HAVE_GNUTLS | |||
- "X509Plain,TLSPlain,X509Vnc,TLSVnc,X509None,TLSNone,VncAuth,None", | |||
+ "VeNCrypt,X509Plain,TLSPlain,X509Vnc,TLSVnc,X509None,TLSNone,VncAuth,None", | |||
#else | |||
"VncAuth,None", | |||
#endif | |||
diff -up tigervnc-1.0.90-20110314svn4359/common/rfb/Security.cxx.rh690245 tigervnc-1.0.90-20110314svn4359/common/rfb/Security.cxx | |||
--- tigervnc-1.0.90-20110314svn4359/common/rfb/Security.cxx.rh690245 2011-02-21 14:14:16.000000000 +0100 | |||
+++ tigervnc-1.0.90-20110314svn4359/common/rfb/Security.cxx 2011-03-31 09:47:34.519099718 +0200 | |||
@@ -67,7 +67,6 @@ const std::list<rdr::U8> Security::GetEn | |||
list<rdr::U8> result; | |||
list<U32>::iterator i; | |||
- result.push_back(secTypeVeNCrypt); | |||
for (i = enabledSecTypes.begin(); i != enabledSecTypes.end(); i++) | |||
if (*i < 0x100) | |||
result.push_back(*i); | |||
@@ -105,8 +104,6 @@ bool Security::IsSupported(U32 secType) | |||
for (i = enabledSecTypes.begin(); i != enabledSecTypes.end(); i++) | |||
if (*i == secType) | |||
return true; | |||
- if (secType == secTypeVeNCrypt) | |||
- return true; | |||
return false; | |||
} | |||
diff -up tigervnc-1.0.90-20110314svn4359/common/rfb/SecurityServer.cxx.rh690245 tigervnc-1.0.90-20110314svn4359/common/rfb/SecurityServer.cxx | |||
--- tigervnc-1.0.90-20110314svn4359/common/rfb/SecurityServer.cxx.rh690245 2011-02-21 14:50:17.000000000 +0100 | |||
+++ tigervnc-1.0.90-20110314svn4359/common/rfb/SecurityServer.cxx 2011-03-31 10:06:43.595362302 +0200 | |||
@@ -39,7 +39,7 @@ StringParameter SecurityServer::secTypes | |||
("SecurityTypes", | |||
"Specify which security scheme to use (None, VncAuth)", | |||
#ifdef HAVE_GNUTLS | |||
- "VncAuth,TLSVnc", | |||
+ "VncAuth", | |||
#else | |||
"VncAuth", | |||
#endif |
@@ -0,0 +1,10 @@ | |||
--- a/unix/xserver/man/Makefile.am 2013-03-30 17:51:01.707258746 -0400 | |||
+++ b/unix/xserver/man/Makefile.am 2013-03-30 17:51:47.606569692 -0400 | |||
@@ -2,5 +2,7 @@ | |||
# (i.e. those handled in the os/utils.c options processing instead of in | |||
# the DDX-level options processing) | |||
+if ENABLE_DOCS | |||
include $(top_srcdir)/manpages.am | |||
appman_PRE = Xserver.man | |||
+endif ENABLE_DOCS |
@@ -0,0 +1,12 @@ | |||
## Patches with a number < 100 are applied in debian. | |||
## Ubuntu patches start with 100. | |||
# Ubuntu patches | |||
100_rethrow_signals.patch | |||
# Upstream patches | |||
504_tigervnc-cookie.patch | |||
510_tigervnc11-ldnow.patch | |||
511_tigervnc11-gethomedir.patch | |||
513_tigervnc11-rh692048.patch | |||
516_tigervnc-xorg-manpages.patch |
@@ -0,0 +1,290 @@ | |||
#!/usr/bin/make -f | |||
# Sample debian/rules that uses debhelper. | |||
# GNU copyright 1997 by Joey Hess. | |||
# Uncomment this to turn on verbose mode. | |||
#export DH_VERBOSE=1 | |||
# These are used for cross-compiling and for saving the configure script | |||
# from having to guess our platform (since we know it already) | |||
#DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) | |||
#DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) | |||
DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH) | |||
DEB_HOST_ARCH ?= $(shell dpkg-architecture -qDEB_HOST_ARCH) | |||
DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) | |||
DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) | |||
DEB_HOST_ARCH_OS ?= $(shell dpkg-architecture -qDEB_HOST_ARCH_OS) | |||
ifeq ($(DEB_BUILD_GNU_TYPE), $(DEB_HOST_GNU_TYPE)) | |||
confflags += --build=$(DEB_HOST_GNU_TYPE) | |||
else | |||
confflags += --build=$(DEB_BUILD_GNU_TYPE) --host=$(DEB_HOST_GNU_TYPE) | |||
endif | |||
SOURCE_NAME := tigervnc | |||
SOURCE_VERSION := $(shell dpkg-parsechangelog | awk -F': ' '/^Version: / {print $$2}') | |||
BUILDER=For technical support please see http://sourceforge.net/projects/tigervnc/support | |||
ifneq (,$(findstring debug,$(DEB_BUILD_OPTIONS))) | |||
CFLAGS += -g -O2 -fPIC | |||
endif | |||
ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS))) | |||
INSTALL_PROGRAM += -s | |||
endif | |||
export CC = gcc | |||
get-orig-source: $(SOURCE_NAME)_$(SOURCE_VERSION).orig.tar.gz | |||
@ | |||
$(SOURCE_NAME)_$(SOURCE_VERSION).orig.tar.gz: | |||
$(CURDIR)/get-orig-source.sh | |||
configure: config-stamp | |||
config-stamp: | |||
dh_testdir | |||
# Add here commands to configure the package. | |||
(cd fltk-*;cmake -G"Unix Makefiles" \ | |||
-DCMAKE_INSTALL_PREFIX=/usr \ | |||
-DCMAKE_BUILD_TYPE=Release \ | |||
-DOPTION_PREFIX_LIB=/usr/lib \ | |||
-DOPTION_PREFIX_CONFIG=/usr/lib \ | |||
-DOPTION_BUILD_EXAMPLES=off \ | |||
-DOPTION_USE_SYSTEM_LIBPNG=on;make) | |||
cmake -G"Unix Makefiles" \ | |||
-DCMAKE_INSTALL_PREFIX=/usr \ | |||
-DFLTK_LIBRARIES="$(CURDIR)/fltk-1.3.2/lib/libfltk.a;$(CURDIR)/fltk-1.3.2/lib/libfltk_images.a;-lpng" \ | |||
-DFLTK_INCLUDE_DIR=$(CURDIR)/fltk-1.3.2 | |||
(cd unix/xserver; \ | |||
export PIXMANINCDIR=/usr/include/pixman-1; \ | |||
autoreconf -fiv; \ | |||
./configure --prefix=/usr \ | |||
--disable-silent-rules \ | |||
--disable-static \ | |||
--without-dtrace \ | |||
--disable-strict-compilation \ | |||
--disable-debug \ | |||
--disable-unit-tests \ | |||
--with-int10=x86emu \ | |||
--with-extra-module-dir="/usr/lib/${DEB_HOST_MULTIARCH}/xorg/extra-modules,/usr/lib/xorg/extra-modules" \ | |||
--with-os-vendor="$(VENDOR)" \ | |||
--with-builderstring="$(SOURCE_NAME) $(SOURCE_VERSION) ($(BUILDER))" \ | |||
--with-xkb-path=/usr/share/X11/xkb \ | |||
--with-xkb-output=/var/lib/xkb \ | |||
--with-default-xkb-rules=evdev \ | |||
--disable-devel-docs \ | |||
--disable-install-libxf86config \ | |||
--enable-mitshm \ | |||
--enable-xres \ | |||
--disable-xcsecurity \ | |||
--disable-xcalibrate \ | |||
--disable-tslib \ | |||
--enable-dbe \ | |||
--disable-xf86bigfont \ | |||
--disable-dpms \ | |||
--disable-config-dbus \ | |||
--disable-config-hal \ | |||
--disable-config-udev \ | |||
--disable-xorg \ | |||
--disable-xquartz \ | |||
--disable-xwin \ | |||
--disable-xfake \ | |||
--disable-install-setuid \ | |||
--enable-gestures \ | |||
--with-default-font-path="/usr/share/fonts/X11/misc,/usr/share/fonts/X11/cyrillic,/usr/share/fonts/X11/100dpi/:unscaled,/usr/share/fonts/X11/75dpi/:unscaled,/usr/share/fonts/X11/Type1,/usr/share/fonts/X11/100dpi,/usr/share/fonts/X11/75dpi,/var/lib/defoma/x-ttcidfont-conf.d/dirs/TrueType,built-ins" \ | |||
--enable-aiglx \ | |||
--enable-glx-tls \ | |||
--enable-registry \ | |||
--enable-composite \ | |||
--enable-record \ | |||
--enable-xv \ | |||
--enable-xvmc \ | |||
--enable-dga \ | |||
--enable-screensaver \ | |||
--enable-xdmcp \ | |||
--enable-xdm-auth-1 \ | |||
--enable-glx \ | |||
--disable-dri --enable-dri2 \ | |||
--disable-xinerama \ | |||
--enable-xf86vidmode \ | |||
--enable-xace \ | |||
--disable-selinux \ | |||
--enable-xfree86-utils \ | |||
--disable-dmx \ | |||
--disable-xvfb \ | |||
--disable-xnest \ | |||
--disable-kdrive \ | |||
--disable-xephyr \ | |||
--enable-xfbdev \ | |||
--with-sha1=libgcrypt \ | |||
--enable-xcsecurity \ | |||
--disable-docs \ | |||
--disable-selective-werror) | |||
touch config-stamp | |||
build-arch: config-stamp build-arch-stamp | |||
build-arch-stamp: | |||
dh_testdir | |||
# Add here command to compile/build the package. | |||
# Build first things. | |||
# Build Xvnc | |||
make LDFLAGS="-lpng" | |||
(cd unix/xserver;make) | |||
touch build-arch-stamp | |||
build-indep: config-stamp build-indep-stamp | |||
build-indep-stamp: | |||
dh_testdir | |||
# Add here command to compile/build the arch indep package. | |||
# It's ok not to do anything here, if you don't need to build | |||
# anything for this package. | |||
#/usr/bin/docbook-to-man debian/vnc.sgml > vnc.1 | |||
(cd media;make) | |||
(cd java;cmake -G"Unix Makefiles";make) | |||
touch build-indep-stamp | |||
build: build-arch build-indep | |||
clean: | |||
dh_testdir | |||
dh_testroot | |||
rm -f build-arch-stamp build-indep-stamp config-stamp | |||
# Add here commands to clean up after the build process. | |||
dh_clean | |||
(cd fltk-*; $(MAKE) distclean; rm configure) | |||
(if [ -e Makefile ] ; then $(MAKE) clean ; fi) | |||
(cd unix/xserver; if [ -e Makefile ] ; then $(MAKE) clean ; fi) | |||
install: DH_OPTIONS= | |||
install: build | |||
dh_testdir | |||
dh_testroot | |||
dh_clean -k | |||
dh_prep | |||
dh_installdirs | |||
# Add here commands to install the package into debian/vnc. | |||
# tigervncserver | |||
make install DESTDIR=$(CURDIR)/debian/tigervncserver | |||
(cd unix/xserver/hw/vnc; make install DESTDIR=$(CURDIR)/debian/tigervncserver) | |||
mv $(CURDIR)/debian/tigervncserver/usr/bin/Xvnc \ | |||
$(CURDIR)/debian/tigervncserver/usr/bin/Xtigervnc | |||
mv $(CURDIR)/debian/tigervncserver/usr/bin/vncconfig \ | |||
$(CURDIR)/debian/tigervncserver/usr/bin/tigervncconfig | |||
mv $(CURDIR)/debian/tigervncserver/usr/bin/vncpasswd \ | |||
$(CURDIR)/debian/tigervncserver/usr/bin/tigervncpasswd | |||
mv $(CURDIR)/debian/tigervncserver/usr/bin/vncserver \ | |||
$(CURDIR)/debian/tigervncserver/usr/bin/tigervncserver | |||
mv $(CURDIR)/debian/tigervncserver/usr/bin/x0vncserver \ | |||
$(CURDIR)/debian/tigervncserver/usr/bin/x0tigervncserver | |||
mv $(CURDIR)/debian/tigervncserver/usr/share/man/man1/vncconfig.1 \ | |||
$(CURDIR)/debian/tigervncserver/usr/share/man/man1/tigervncconfig.1 | |||
mv $(CURDIR)/debian/tigervncserver/usr/share/man/man1/vncpasswd.1 \ | |||
$(CURDIR)/debian/tigervncserver/usr/share/man/man1/tigervncpasswd.1 | |||
mv $(CURDIR)/debian/tigervncserver/usr/share/man/man1/vncserver.1 \ | |||
$(CURDIR)/debian/tigervncserver/usr/share/man/man1/tigervncserver.1 | |||
mv $(CURDIR)/debian/tigervncserver/usr/share/man/man1/x0vncserver.1 \ | |||
$(CURDIR)/debian/tigervncserver/usr/share/man/man1/x0tigervncserver.1 | |||
mv $(CURDIR)/debian/tigervncserver/usr/share/man/man1/Xvnc.1 \ | |||
$(CURDIR)/debian/tigervncserver/usr/share/man/man1/Xtigervnc.1 | |||
mv $(CURDIR)/debian/tigervncserver/usr/share/doc/tigervnc-* \ | |||
$(CURDIR)/debian/tigervncserver/usr/share/doc/tigervncserver | |||
rm $(CURDIR)/debian/tigervncserver/usr/lib/xorg/modules/extensions/libvnc.la | |||
rm $(CURDIR)/debian/tigervncserver/usr/bin/vncviewer | |||
rm $(CURDIR)/debian/tigervncserver/usr/share/man/man1/vncviewer.1 | |||
install -o root -g root -m 755 -D $(CURDIR)/debian/local/vncserver.service \ | |||
$(CURDIR)/debian/tigervncserver/etc/init.d/vncserver | |||
install -o root -g root -m 644 -D $(CURDIR)/debian/local/vncserver.sysconfig \ | |||
$(CURDIR)/debian/tigervncserver/etc/default/vncservers | |||
# xtigervncviewer | |||
(cd vncviewer; make install DESTDIR=$(CURDIR)/debian/xtigervncviewer) | |||
# Install desktop stuff | |||
mv $(CURDIR)/debian/xtigervncviewer/usr/bin/vncviewer \ | |||
$(CURDIR)/debian/xtigervncviewer/usr/bin/xtigervncviewer | |||
mv $(CURDIR)/debian/xtigervncviewer/usr/share/man/man1/vncviewer.1 \ | |||
$(CURDIR)/debian/xtigervncviewer/usr/share/man/man1/xtigervncviewer.1 | |||
install -o root -g root -m 644 -D media/icons/tigervnc_16.png \ | |||
$(CURDIR)/debian/xtigervncviewer/usr/share/icons/hicolor/16x16/apps/tigervnc.png | |||
install -o root -g root -m 644 -D media/icons/tigervnc_22.png \ | |||
$(CURDIR)/debian/xtigervncviewer/usr/share/icons/hicolor/22x22/apps/tigervnc.png | |||
install -o root -g root -m 644 -D media/icons/tigervnc_24.png \ | |||
$(CURDIR)/debian/xtigervncviewer/usr/share/icons/hicolor/24x24/apps/tigervnc.png | |||
install -o root -g root -m 644 -D media/icons/tigervnc_32.png \ | |||
$(CURDIR)/debian/xtigervncviewer/usr/share/icons/hicolor/32x32/apps/tigervnc.png | |||
install -o root -g root -m 644 -D media/icons/tigervnc_48.png \ | |||
$(CURDIR)/debian/xtigervncviewer/usr/share/icons/hicolor/48x48/apps/tigervnc.png | |||
install -o root -g root -m 644 -D media/icons/tigervnc.svg \ | |||
$(CURDIR)/debian/xtigervncviewer/usr/share/icons/hicolor/scalable/apps/tigervnc.svg | |||
# tigervnc-java | |||
mkdir -p $(CURDIR)/debian/tigervnc-java/usr/share | |||
(cd java; make install DESTDIR=$(CURDIR)/debian/tigervnc-java/usr/share) | |||
#dh_movefiles | |||
# Build architecture-independent files here. | |||
# Pass -i to all debhelper commands in this target to reduce clutter. | |||
binary-indep: build install | |||
binary-indep-keep: | |||
dh_testdir -i | |||
dh_testroot -i | |||
# dh_installdebconf -i | |||
dh_install | |||
dh_installdocs -i | |||
dh_installexamples -i | |||
dh_installmenu -i | |||
# dh_installlogrotate -i | |||
# dh_installemacsen -i | |||
# dh_installpam -i | |||
# dh_installmime -i | |||
# dh_installinit -i | |||
dh_installcron -i | |||
dh_installman -i | |||
dh_installinfo -i | |||
# dh_undocumented -i | |||
dh_installchangelogs -i | |||
dh_link -i | |||
dh_compress -i | |||
dh_fixperms -i | |||
dh_installdeb -i | |||
dh_perl -i | |||
dh_gencontrol -i | |||
dh_md5sums -i | |||
dh_builddeb -i | |||
# Build architecture-dependent files here. | |||
binary-arch: build install | |||
dh_testdir -a | |||
dh_testroot -a | |||
# dh_installdebconf -a | |||
dh_installdocs -a | |||
# dh_installexamples -a | |||
dh_installmenu -a | |||
# dh_installlogrotate -a | |||
# dh_installemacsen -a | |||
# dh_installpam -a | |||
# dh_installmime -a | |||
dh_install | |||
dh_installinit -a | |||
# dh_installcron -a | |||
dh_installman -a | |||
dh_installinfo -a | |||
# dh_undocumented -a | |||
dh_installchangelogs -a | |||
# Remove empty directories | |||
dh_strip -a | |||
dh_link -a | |||
dh_compress -a | |||
dh_fixperms -a | |||
dh_makeshlibs -a | |||
dh_installdeb -a | |||
dh_perl -a | |||
dh_shlibdeps -a | |||
dh_gencontrol -a | |||
dh_md5sums -a | |||
dh_builddeb -a | |||
binary: binary-indep binary-arch | |||
.PHONY: build clean binary-indep binary-arch binary install get-orig-source |
@@ -0,0 +1 @@ | |||
3.0 (quilt) |
@@ -0,0 +1,30 @@ | |||
#!/bin/sh -e | |||
if [ "$1" = "configure" ]; then | |||
MAN=/usr/share/man/man1 | |||
BIN=/usr/bin | |||
update-alternatives --install \ | |||
$BIN/vncserver vncserver $BIN/tigervncserver 64 \ | |||
--slave \ | |||
$MAN/vncserver.1.gz vncserver.1.gz $MAN/tigervncserver.1.gz | |||
update-alternatives --install \ | |||
$BIN/Xvnc Xvnc $BIN/Xtigervnc 74 \ | |||
--slave \ | |||
$MAN/Xvnc.1.gz Xvnc.1.gz $MAN/Xtigervnc.1.gz | |||
update-alternatives --install \ | |||
$BIN/x0vncserver x0vncserver $BIN/x0tigervncserver 74 \ | |||
--slave \ | |||
$MAN/x0vncserver.1.gz x0vncserver.1.gz $MAN/x0tigervncserver.1.gz | |||
update-alternatives --install \ | |||
$BIN/vncpasswd vncpasswd $BIN/tigervncpasswd 74 \ | |||
--slave \ | |||
$MAN/vncpasswd.1.gz vncpasswd.1.gz $MAN/tigervncpasswd.1.gz | |||
update-alternatives --install \ | |||
$BIN/vncconfig vncconfig $BIN/tigervncconfig 64 \ | |||
--slave \ | |||
$MAN/vncconfig.1.gz vncconfig.1.gz $MAN/tigervncconfig.1.gz | |||
fi | |||
#DEBHELPER# | |||
exit 0 |
@@ -0,0 +1,19 @@ | |||
#!/bin/sh -e | |||
if [ "$1" = "remove" ] ; then | |||
BIN=/usr/bin | |||
update-alternatives --remove \ | |||
vncserver $BIN/tigervncserver | |||
update-alternatives --remove \ | |||
Xvnc $BIN/Xtigervnc | |||
update-alternatives --remove \ | |||
x0vncserver $BIN/x0tigervncserver | |||
update-alternatives --remove \ | |||
vncpasswd $BIN/tigervncpasswd | |||
update-alternatives --remove \ | |||
tigervncconfig $BIN/tigervncconfig | |||
fi | |||
#DEBHELPER# | |||
exit 0 |
@@ -0,0 +1,5 @@ | |||
?package(xtigervncviewer):needs="x11" \ | |||
section="Applications/Network/Communication" \ | |||
hints="VNC,remote-control"\ | |||
title="xtigervncviewer" \ | |||
command="/usr/bin/xtigervncviewer" |
@@ -0,0 +1,18 @@ | |||
#!/bin/sh -e | |||
if [ "$1" = "configure" ]; then | |||
MAN=/usr/share/man/man1 | |||
BIN=/usr/bin | |||
update-alternatives --install \ | |||
$BIN/vncviewer vncviewer $BIN/xtigervncviewer 74 \ | |||
--slave \ | |||
$MAN/vncviewer.1.gz vncviewer.1.gz $MAN/xtigervncviewer.1.gz \ | |||
--slave \ | |||
$MAN/xvncviewer.1.gz xvncviewer.1.gz $MAN/xtigervncviewer.1.gz \ | |||
--slave \ | |||
$BIN/xvncviewer xvncviewer $BIN/xtigervncviewer | |||
fi | |||
#DEBHELPER# | |||
exit 0 |
@@ -0,0 +1,11 @@ | |||
#!/bin/sh -e | |||
if [ "$1" = "remove" ] ; then | |||
BIN=/usr/bin | |||
update-alternatives --remove \ | |||
vncviewer $BIN/xtigervncviewer | |||
fi | |||
#DEBHELPER# | |||
exit 0 |
@@ -0,0 +1,114 @@ | |||
From ef2807731903ff05a618fe2cbd532fe2472f7d0d Mon Sep 17 00:00:00 2001 | |||
From: Adam Jackson <ajax@redhat.com> | |||
Date: Tue, 27 Sep 2011 14:56:00 -0400 | |||
Subject: [PATCH] CVE-2011-4818: Additional coverage for swap barriers and | |||
hyperpipe | |||
These have since been dropped, so the straight backport does not cover | |||
these cases. | |||
Signed-off-by: Adam Jackson <ajax@redhat.com> | |||
--- | |||
glx/glxcmds.c | 30 ++++++++++++++++++++++++------ | |||
1 files changed, 24 insertions(+), 6 deletions(-) | |||
diff --git a/glx/glxcmds.c b/glx/glxcmds.c | |||
index 922a6c1..fd0df31 100644 | |||
--- a/glx/glxcmds.c | |||
+++ b/glx/glxcmds.c | |||
@@ -2204,6 +2204,8 @@ int __glXDisp_BindSwapBarrierSGIX(__GLXclientState *cl, GLbyte *pc) | |||
int screen, rc; | |||
__GLXscreen *pGlxScreen; | |||
+ REQUEST_SIZE_MATCH(xGLXBindSwapBarrierSGIXReq); | |||
+ | |||
rc = dixLookupDrawable(&pDraw, drawable, client, 0, DixGetAttrAccess); | |||
pGlxScreen = glxGetScreen(pDraw->pScreen); | |||
if (rc == Success && (pDraw->type == DRAWABLE_WINDOW)) { | |||
@@ -2233,9 +2235,13 @@ int __glXDisp_QueryMaxSwapBarriersSGIX(__GLXclientState *cl, GLbyte *pc) | |||
(xGLXQueryMaxSwapBarriersSGIXReq *) pc; | |||
xGLXQueryMaxSwapBarriersSGIXReply reply; | |||
int screen = req->screen; | |||
+ int err; | |||
__GLXscreen *pGlxScreen; | |||
- pGlxScreen = glxGetScreen(screenInfo.screens[screen]); | |||
+ REQUEST_SIZE_MATCH(xGLXQueryMaxSwapBarriersSGIXReq); | |||
+ if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) | |||
+ return err; | |||
+ | |||
if (pGlxScreen->swapBarrierFuncs) | |||
reply.max = pGlxScreen->swapBarrierFuncs->queryMaxSwapBarriersFunc(screen); | |||
else | |||
@@ -2265,14 +2271,17 @@ int __glXDisp_QueryHyperpipeNetworkSGIX(__GLXclientState *cl, GLbyte *pc) | |||
xGLXQueryHyperpipeNetworkSGIXReply reply; | |||
int screen = req->screen; | |||
void *rdata = NULL; | |||
- | |||
+ int err; | |||
int length=0; | |||
int npipes=0; | |||
int n= 0; | |||
__GLXscreen *pGlxScreen; | |||
- pGlxScreen = glxGetScreen(screenInfo.screens[screen]); | |||
+ REQUEST_SIZE_MATCH(xGLXQueryHyperpipeNetworkSGIXReq); | |||
+ | |||
+ if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) | |||
+ return err; | |||
if (pGlxScreen->hyperpipeFuncs) { | |||
rdata = | |||
(pGlxScreen->hyperpipeFuncs->queryHyperpipeNetworkFunc(screen, &npipes, &n)); | |||
@@ -2308,11 +2317,14 @@ int __glXDisp_DestroyHyperpipeConfigSGIX (__GLXclientState *cl, GLbyte *pc) | |||
int screen = req->screen; | |||
int success = GLX_BAD_HYPERPIPE_SGIX; | |||
int hpId ; | |||
+ int err; | |||
__GLXscreen *pGlxScreen; | |||
hpId = req->hpId; | |||
- pGlxScreen = glxGetScreen(screenInfo.screens[screen]); | |||
+ REQUEST_SIZE_MATCH(xGLXDestroyHyperpipeConfigSGIXReq); | |||
+ if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) | |||
+ return err; | |||
if (pGlxScreen->hyperpipeFuncs) { | |||
success = pGlxScreen->hyperpipeFuncs->destroyHyperpipeConfigFunc(screen, hpId); | |||
} | |||
@@ -2346,11 +2358,14 @@ int __glXDisp_QueryHyperpipeConfigSGIX(__GLXclientState *cl, GLbyte *pc) | |||
int npipes=0; | |||
int n= 0; | |||
int hpId; | |||
+ int err; | |||
__GLXscreen *pGlxScreen; | |||
hpId = req->hpId; | |||
- pGlxScreen = glxGetScreen(screenInfo.screens[screen]); | |||
+ REQUEST_SIZE_MATCH(xGLXQueryHyperpipeConfigSGIXReq); | |||
+ if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) | |||
+ return err; | |||
if (pGlxScreen->hyperpipeFuncs) { | |||
rdata = pGlxScreen->hyperpipeFuncs->queryHyperpipeConfigFunc(screen, hpId,&npipes, &n); | |||
} | |||
@@ -2387,12 +2402,15 @@ int __glXDisp_HyperpipeConfigSGIX(__GLXclientState *cl, GLbyte *pc) | |||
xGLXHyperpipeConfigSGIXReply reply; | |||
int screen = req->screen; | |||
void *rdata; | |||
+ int err; | |||
int npipes=0, networkId; | |||
int hpId=-1; | |||
__GLXscreen *pGlxScreen; | |||
- pGlxScreen = glxGetScreen(screenInfo.screens[screen]); | |||
+ REQUEST_SIZE_MATCH(xGLXHyperpipeConfigSGIXReq); | |||
+ if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) | |||
+ return err; | |||
networkId = (int)req->networkId; | |||
npipes = (int)req->npipes; | |||
rdata = (void *)(req +1); | |||
-- | |||
1.7.6 | |||
@@ -0,0 +1,51 @@ | |||
--- libX11-1.0.3/modules/im/ximcp/imDefLkup.c.dont-forward-keycode-0 2006-06-22 17:22:22.000000000 -0400 | |||
+++ libX11-1.0.3/modules/im/ximcp/imDefLkup.c 2006-09-20 17:57:49.000000000 -0400 | |||
@@ -332,6 +332,17 @@ | |||
XEvent *ev, | |||
Bool sync) | |||
{ | |||
+ /* | |||
+ * Don't forward a key event which has keycode=0. | |||
+ * keycode=0 is reserved for special purpose to let Xmb/wcLookupString() | |||
+ * functions know that there is a commited string available from IM. | |||
+ */ | |||
+ if (((ev->type == KeyPress) || (ev->type == KeyRelease))) { | |||
+ if (((XKeyEvent *)ev)->keycode == 0) { | |||
+ return True; | |||
+ } | |||
+ } | |||
+ | |||
#ifdef EXT_FORWARD | |||
if (((ev->type == KeyPress) || (ev->type == KeyRelease))) | |||
if (_XimExtForwardKeyEvent(ic, (XKeyEvent *)ev, sync)) | |||
@@ -605,6 +616,19 @@ | |||
Xfree(info->keysym); | |||
ic->private.proto.commit_info = info->next; | |||
Xfree(info); | |||
+ | |||
+ /* | |||
+ * "Commit" uses fabricated flag to process a commited string | |||
+ * from IM engine. | |||
+ * Turn off the fabricated flag here (unregister the commited | |||
+ * information function). Otherwise, next regular key press | |||
+ * event will be ignored at _XimProtoKeypressFilter() and it | |||
+ * will not be passed to IM engine. | |||
+ */ | |||
+ if (IS_FABLICATED(ic)) { | |||
+ UNMARK_FABLICATED(ic); | |||
+ } | |||
+ | |||
return; | |||
} | |||
--- libX11-1.0.3/modules/im/ximcp/imDefFlt.c.dont-forward-keycode-0 2006-06-22 17:22:22.000000000 -0400 | |||
+++ libX11-1.0.3/modules/im/ximcp/imDefFlt.c 2006-09-20 17:57:49.000000000 -0400 | |||
@@ -147,7 +147,7 @@ | |||
Xim im = (Xim)ic->core.im; | |||
#endif | |||
- if (IS_FABLICATED(ic)) { | |||
+ if ((ev->keycode == 0) || IS_FABLICATED(ic)) { | |||
_XimPendingFilter(ic); | |||
UNMARK_FABLICATED(ic); | |||
return NOTFILTERD; |
@@ -0,0 +1,106 @@ | |||
diff -up fltk-1.3.x-r8659/FL/Fl.H.orig fltk-1.3.x-r8659/FL/Fl.H | |||
--- fltk-1.3.x-r8659/FL/Fl.H.orig 2011-05-17 16:25:56.671744548 +0200 | |||
+++ fltk-1.3.x-r8659/FL/Fl.H 2011-05-17 16:26:05.709101536 +0200 | |||
@@ -108,6 +108,9 @@ typedef int (*Fl_Args_Handler)(int argc, | |||
\see Fl::event_dispatch(Fl_Event_Dispatch) */ | |||
typedef int (*Fl_Event_Dispatch)(int event, Fl_Window *w); | |||
+/** Signature of add_clipboard_notify functions passed as parameters */ | |||
+typedef void (*Fl_Clipboard_Notify_Handler)(int source, void *data); | |||
+ | |||
/** @} */ /* group callback_functions */ | |||
@@ -744,6 +747,19 @@ public: | |||
*/ | |||
static void paste(Fl_Widget &receiver, int source /*=0*/); // platform dependent | |||
/** | |||
+ FLTK will call the registered callback whenever there is a change to the | |||
+ selection buffer or the clipboard. The source argument indicates which | |||
+ of the two has changed. Only changes by other applications are reported. | |||
+ \note Some systems require polling to monitor the clipboard and may | |||
+ therefore have some delay in detecting changes. | |||
+ */ | |||
+ static void add_clipboard_notify(Fl_Clipboard_Notify_Handler h, void *data); | |||
+ /** | |||
+ Stop calling the specified callback when there are changes to the selection | |||
+ buffer or the clipboard. | |||
+ */ | |||
+ static void remove_clipboard_notify(Fl_Clipboard_Notify_Handler h); | |||
+ /** | |||
Initiate a Drag And Drop operation. The selection buffer should be | |||
filled with relevant data before calling this method. FLTK will | |||
then initiate the system wide drag and drop handling. Dropped data | |||
diff -up fltk-1.3.x-r8659/src/Fl.cxx.orig fltk-1.3.x-r8659/src/Fl.cxx | |||
--- fltk-1.3.x-r8659/src/Fl.cxx.orig 2011-05-18 15:20:26.667291459 +0200 | |||
+++ fltk-1.3.x-r8659/src/Fl.cxx 2011-05-18 16:31:15.522026086 +0200 | |||
@@ -430,6 +430,69 @@ static char in_idle; | |||
#endif | |||
//////////////////////////////////////////////////////////////// | |||
+// Clipboard notifications | |||
+ | |||
+struct Clipboard_Notify { | |||
+ Fl_Clipboard_Notify_Handler handler; | |||
+ void *data; | |||
+ struct Clipboard_Notify *next; | |||
+}; | |||
+ | |||
+static struct Clipboard_Notify *clip_notify_list = NULL; | |||
+ | |||
+extern void fl_clipboard_notify_change(); // in Fl_<platform>.cxx | |||
+ | |||
+void Fl::add_clipboard_notify(Fl_Clipboard_Notify_Handler h, void *data) { | |||
+ struct Clipboard_Notify *node; | |||
+ | |||
+ remove_clipboard_notify(h); | |||
+ | |||
+ node = new Clipboard_Notify; | |||
+ | |||
+ node->handler = h; | |||
+ node->data = data; | |||
+ node->next = clip_notify_list; | |||
+ | |||
+ clip_notify_list = node; | |||
+ | |||
+ fl_clipboard_notify_change(); | |||
+} | |||
+ | |||
+void Fl::remove_clipboard_notify(Fl_Clipboard_Notify_Handler h) { | |||
+ struct Clipboard_Notify *node, **prev; | |||
+ | |||
+ node = clip_notify_list; | |||
+ prev = &clip_notify_list; | |||
+ while (node != NULL) { | |||
+ if (node->handler == h) { | |||
+ *prev = node->next; | |||
+ delete node; | |||
+ | |||
+ fl_clipboard_notify_change(); | |||
+ | |||
+ return; | |||
+ } | |||
+ | |||
+ prev = &node->next; | |||
+ node = node->next; | |||
+ } | |||
+} | |||
+ | |||
+bool fl_clipboard_notify_empty(void) { | |||
+ return clip_notify_list == NULL; | |||
+} | |||
+ | |||
+void fl_trigger_clipboard_notify(int source) { | |||
+ struct Clipboard_Notify *node; | |||
+ | |||
+ node = clip_notify_list; | |||
+ while (node != NULL) { | |||
+ node->handler(source, node->data); | |||
+ node = node->next; | |||
+ } | |||
+} | |||
+ | |||
+//////////////////////////////////////////////////////////////// | |||
// wait/run/check/ready: | |||
void (*Fl::idle)(); // see Fl::add_idle.cxx for the add/remove functions |
@@ -0,0 +1,131 @@ | |||
diff -up fltk-1.3.0r9619/FL/Fl.H.screen_num fltk-1.3.0r9619/FL/Fl.H | |||
--- fltk-1.3.0r9619/FL/Fl.H.screen_num 2012-07-03 13:49:28.663085580 +0200 | |||
+++ fltk-1.3.0r9619/FL/Fl.H 2012-07-03 13:49:28.731084402 +0200 | |||
@@ -806,6 +806,8 @@ public: | |||
static void screen_xywh(int &X, int &Y, int &W, int &H, int mx, int my); | |||
static void screen_xywh(int &X, int &Y, int &W, int &H, int n); | |||
static void screen_xywh(int &X, int &Y, int &W, int &H, int mx, int my, int mw, int mh); | |||
+ static int screen_num(int x, int y); | |||
+ static int screen_num(int x, int y, int w, int h); | |||
static void screen_dpi(float &h, float &v, int n=0); | |||
static void screen_work_area(int &X, int &Y, int &W, int &H, int mx, int my); | |||
static void screen_work_area(int &X, int &Y, int &W, int &H, int n); | |||
diff -up fltk-1.3.0r9619/src/screen_xywh.cxx.screen_num fltk-1.3.0r9619/src/screen_xywh.cxx | |||
--- fltk-1.3.0r9619/src/screen_xywh.cxx.screen_num 2012-03-23 17:47:53.000000000 +0100 | |||
+++ fltk-1.3.0r9619/src/screen_xywh.cxx 2012-07-03 13:58:01.947195396 +0200 | |||
@@ -215,21 +215,6 @@ int Fl::screen_count() { | |||
return num_screens ? num_screens : 1; | |||
} | |||
-static int find_screen_with_point(int mx, int my) { | |||
- int screen = 0; | |||
- if (num_screens < 0) screen_init(); | |||
- | |||
- for (int i = 0; i < num_screens; i ++) { | |||
- int sx, sy, sw, sh; | |||
- Fl::screen_xywh(sx, sy, sw, sh, i); | |||
- if ((mx >= sx) && (mx < (sx+sw)) && (my >= sy) && (my < (sy+sh))) { | |||
- screen = i; | |||
- break; | |||
- } | |||
- } | |||
- return screen; | |||
-} | |||
- | |||
/** | |||
Gets the bounding box of a screen | |||
that contains the specified screen position \p mx, \p my | |||
@@ -237,7 +222,7 @@ static int find_screen_with_point(int mx | |||
\param[in] mx, my the absolute screen position | |||
*/ | |||
void Fl::screen_xywh(int &X, int &Y, int &W, int &H, int mx, int my) { | |||
- screen_xywh(X, Y, W, H, find_screen_with_point(mx, my)); | |||
+ screen_xywh(X, Y, W, H, screen_num(mx, my)); | |||
} | |||
@@ -248,7 +233,7 @@ void Fl::screen_xywh(int &X, int &Y, int | |||
\param[in] mx, my the absolute screen position | |||
*/ | |||
void Fl::screen_work_area(int &X, int &Y, int &W, int &H, int mx, int my) { | |||
- screen_work_area(X, Y, W, H, find_screen_with_point(mx, my)); | |||
+ screen_work_area(X, Y, W, H, screen_num(mx, my)); | |||
} | |||
/** | |||
@@ -321,6 +306,38 @@ void Fl::screen_xywh(int &X, int &Y, int | |||
#endif // WIN32 | |||
} | |||
+/** | |||
+ Gets the screen bounding rect for the screen | |||
+ which intersects the most with the rectangle | |||
+ defined by \p mx, \p my, \p mw, \p mh. | |||
+ \param[out] X,Y,W,H the corresponding screen bounding box | |||
+ \param[in] mx, my, mw, mh the rectangle to search for intersection with | |||
+ \see void screen_xywh(int &X, int &Y, int &W, int &H, int n) | |||
+ */ | |||
+void Fl::screen_xywh(int &X, int &Y, int &W, int &H, int mx, int my, int mw, int mh) { | |||
+ screen_xywh(X, Y, W, H, screen_num(mx, my, mw, mh)); | |||
+} | |||
+ | |||
+/** | |||
+ Gets the screen number of a screen | |||
+ that contains the specified screen position \p x, \p y | |||
+ \param[in] x, y the absolute screen position | |||
+*/ | |||
+int Fl::screen_num(int x, int y) { | |||
+ int screen = 0; | |||
+ if (num_screens < 0) screen_init(); | |||
+ | |||
+ for (int i = 0; i < num_screens; i ++) { | |||
+ int sx, sy, sw, sh; | |||
+ Fl::screen_xywh(sx, sy, sw, sh, i); | |||
+ if ((x >= sx) && (x < (sx+sw)) && (y >= sy) && (y < (sy+sh))) { | |||
+ screen = i; | |||
+ break; | |||
+ } | |||
+ } | |||
+ return screen; | |||
+} | |||
+ | |||
static inline float fl_intersection(int x1, int y1, int w1, int h1, | |||
int x2, int y2, int w2, int h2) { | |||
if(x1+w1 < x2 || x2+w2 < x1 || y1+h1 < y2 || y2+h2 < y1) | |||
@@ -333,30 +350,27 @@ static inline float fl_intersection(int | |||
} | |||
/** | |||
- Gets the screen bounding rect for the screen | |||
+ Gets the screen number for the screen | |||
which intersects the most with the rectangle | |||
- defined by \p mx, \p my, \p mw, \p mh. | |||
- \param[out] X,Y,W,H the corresponding screen bounding box | |||
- \param[in] mx, my, mw, mh the rectangle to search for intersection with | |||
- \see void screen_xywh(int &X, int &Y, int &W, int &H, int n) | |||
+ defined by \p x, \p y, \p w, \p h. | |||
+ \param[in] x, y, w, h the rectangle to search for intersection with | |||
*/ | |||
-void Fl::screen_xywh(int &X, int &Y, int &W, int &H, int mx, int my, int mw, int mh) { | |||
+int Fl::screen_num(int x, int y, int w, int h) { | |||
int best_screen = 0; | |||
float best_intersection = 0.; | |||
for(int i = 0; i < Fl::screen_count(); i++) { | |||
int sx, sy, sw, sh; | |||
Fl::screen_xywh(sx, sy, sw, sh, i); | |||
- float sintersection = fl_intersection(mx, my, mw, mh, sx, sy, sw, sh); | |||
+ float sintersection = fl_intersection(x, y, w, h, sx, sy, sw, sh); | |||
if(sintersection > best_intersection) { | |||
best_screen = i; | |||
best_intersection = sintersection; | |||
} | |||
} | |||
- screen_xywh(X, Y, W, H, best_screen); | |||
+ return best_screen; | |||
} | |||
- | |||
/** | |||
Gets the screen resolution in dots-per-inch for the given screen. | |||
\param[out] h, v horizontal and vertical resolution |
@@ -0,0 +1,75 @@ | |||
diff -bur fltk-1.3.0r9619.org/src/Fl_cocoa.mm fltk-1.3.0r9619/src/Fl_cocoa.mm | |||
--- fltk-1.3.0r9619.org/src/Fl_cocoa.mm 2012-06-19 12:54:43.694231638 +0200 | |||
+++ fltk-1.3.0r9619/src/Fl_cocoa.mm 2012-06-19 12:57:05.899048602 +0200 | |||
@@ -697,12 +697,9 @@ | |||
return NO; // prevent the caption to be redrawn as active on click | |||
// when another modal window is currently the key win | |||
- return !(w->tooltip_window() || w->menu_window()); | |||
+ return !w->tooltip_window(); | |||
} | |||
-// TODO see if we really need a canBecomeMainWindow ... | |||
-#if 0 | |||
- | |||
- (BOOL)canBecomeMainWindow | |||
{ | |||
if (Fl::modal_ && (Fl::modal_ != w)) | |||
@@ -711,7 +708,6 @@ | |||
return !(w->tooltip_window() || w->menu_window()); | |||
} | |||
-#endif | |||
@end | |||
diff -bur fltk-1.3.0r9619.org/src/Fl_win32.cxx fltk-1.3.0r9619/src/Fl_win32.cxx | |||
--- fltk-1.3.0r9619.org/src/Fl_win32.cxx 2012-06-19 12:54:43.696231735 +0200 | |||
+++ fltk-1.3.0r9619/src/Fl_win32.cxx 2012-06-19 12:54:43.803236862 +0200 | |||
@@ -1065,6 +1065,10 @@ | |||
break; | |||
case WM_SETFOCUS: | |||
+ if ((Fl::modal_) && (Fl::modal_ != window)) { | |||
+ SetFocus(fl_xid(Fl::modal_)); | |||
+ return 0; | |||
+ } | |||
Fl::handle(FL_FOCUS, window); | |||
break; | |||
@@ -1826,6 +1830,11 @@ | |||
Fl::e_number = old_event; | |||
w->redraw(); // force draw to happen | |||
} | |||
+ | |||
+ // Needs to be done before ShowWindow() to get the correct behaviour | |||
+ // when we get WM_SETFOCUS. | |||
+ if (w->modal()) {Fl::modal_ = w; fl_fix_focus();} | |||
+ | |||
// If we've captured the mouse, we dont want to activate any | |||
// other windows from the code, or we lose the capture. | |||
ShowWindow(x->xid, !showit ? SW_SHOWMINNOACTIVE : | |||
@@ -1843,7 +1852,6 @@ | |||
} | |||
} | |||
- if (w->modal()) {Fl::modal_ = w; fl_fix_focus();} | |||
return x; | |||
} | |||
diff -bur fltk-1.3.0r9619.org/src/Fl_x.cxx fltk-1.3.0r9619/src/Fl_x.cxx | |||
--- fltk-1.3.0r9619.org/src/Fl_x.cxx 2012-06-19 12:54:43.697231783 +0200 | |||
+++ fltk-1.3.0r9619/src/Fl_x.cxx 2012-06-19 12:54:43.804236911 +0200 | |||
@@ -2101,6 +2101,12 @@ | |||
while (wp->parent()) wp = wp->window(); | |||
XSetTransientForHint(fl_display, xp->xid, fl_xid(wp)); | |||
if (!wp->visible()) showit = 0; // guess that wm will not show it | |||
+ if (win->modal()) { | |||
+ Atom net_wm_state = XInternAtom (fl_display, "_NET_WM_STATE", 0); | |||
+ Atom net_wm_state_skip_taskbar = XInternAtom (fl_display, "_NET_WM_STATE_MODAL", 0); | |||
+ XChangeProperty (fl_display, xp->xid, net_wm_state, XA_ATOM, 32, | |||
+ PropModeAppend, (unsigned char*) &net_wm_state_skip_taskbar, 1); | |||
+ } | |||
} | |||
// Make sure that borderless windows do not show in the task bar |
@@ -0,0 +1,44 @@ | |||
diff -bur fltk-1.3.0r9619.org/src/Fl_cocoa.mm fltk-1.3.0r9619/src/Fl_cocoa.mm | |||
--- fltk-1.3.0r9619.org/src/Fl_cocoa.mm 2012-06-18 19:24:30.971688769 +0200 | |||
+++ fltk-1.3.0r9619/src/Fl_cocoa.mm 2012-06-18 19:25:25.700310375 +0200 | |||
@@ -1319,9 +1319,13 @@ | |||
} | |||
@end | |||
+static void clipboard_check(void); | |||
+ | |||
@implementation FLApplication | |||
+ (void)sendEvent:(NSEvent *)theEvent | |||
{ | |||
+ // update clipboard status | |||
+ clipboard_check(); | |||
NSEventType type = [theEvent type]; | |||
if (type == NSLeftMouseDown) { | |||
fl_lock_function(); | |||
@@ -2790,6 +2794,26 @@ | |||
PasteboardCreate(kPasteboardClipboard, &myPasteboard); | |||
} | |||
+extern void fl_trigger_clipboard_notify(int source); | |||
+ | |||
+void fl_clipboard_notify_change() { | |||
+ // No need to do anything here... | |||
+} | |||
+ | |||
+static void clipboard_check(void) | |||
+{ | |||
+ PasteboardSyncFlags flags; | |||
+ | |||
+ allocatePasteboard(); | |||
+ flags = PasteboardSynchronize(myPasteboard); | |||
+ | |||
+ if (!(flags & kPasteboardModified)) | |||
+ return; | |||
+ if (flags & kPasteboardClientIsOwner) | |||
+ return; | |||
+ | |||
+ fl_trigger_clipboard_notify(1); | |||
+} | |||
/* | |||
* create a selection |
@@ -0,0 +1,99 @@ | |||
diff -ur fltk-1.3.0r9110.org/src/Fl.cxx fltk-1.3.0r9110/src/Fl.cxx | |||
--- fltk-1.3.0r9110.org/src/Fl.cxx 2012-06-17 19:47:09.988183253 +0200 | |||
+++ fltk-1.3.0r9110/src/Fl.cxx 2012-06-17 19:47:10.127189919 +0200 | |||
@@ -1421,6 +1421,7 @@ | |||
// hide() destroys the X window, it does not do unmap! | |||
#if defined(WIN32) | |||
+extern void fl_clipboard_notify_untarget(HWND wnd); | |||
extern void fl_update_clipboard(void); | |||
#elif USE_XFT | |||
extern void fl_destroy_xft_draw(Window); | |||
@@ -1471,6 +1472,8 @@ | |||
// to destroy the window that owns the selection. | |||
if (GetClipboardOwner()==ip->xid) | |||
fl_update_clipboard(); | |||
+ // Make sure we unlink this window from the clipboard chain | |||
+ fl_clipboard_notify_untarget(ip->xid); | |||
// Send a message to myself so that I'll get out of the event loop... | |||
PostMessage(ip->xid, WM_APP, 0, 0); | |||
if (ip->private_dc) fl_release_dc(ip->xid, ip->private_dc); | |||
diff -ur fltk-1.3.0r9110.org/src/Fl_win32.cxx fltk-1.3.0r9110/src/Fl_win32.cxx | |||
--- fltk-1.3.0r9110.org/src/Fl_win32.cxx 2012-06-17 19:47:09.987183205 +0200 | |||
+++ fltk-1.3.0r9110/src/Fl_win32.cxx 2012-06-17 19:47:19.069618739 +0200 | |||
@@ -646,6 +646,38 @@ | |||
} | |||
} | |||
+static HWND clipboard_wnd = 0; | |||
+static HWND next_clipboard_wnd = 0; | |||
+ | |||
+static bool initial_clipboard = true; | |||
+ | |||
+void fl_clipboard_notify_change() { | |||
+ // No need to do anything here... | |||
+} | |||
+ | |||
+void fl_clipboard_notify_target(HWND wnd) { | |||
+ if (clipboard_wnd) | |||
+ return; | |||
+ | |||
+ // We get one fake WM_DRAWCLIPBOARD immediately, which we therefore | |||
+ // need to ignore. | |||
+ initial_clipboard = true; | |||
+ | |||
+ clipboard_wnd = wnd; | |||
+ next_clipboard_wnd = SetClipboardViewer(wnd); | |||
+} | |||
+ | |||
+void fl_clipboard_notify_untarget(HWND wnd) { | |||
+ if (wnd != clipboard_wnd) | |||
+ return; | |||
+ | |||
+ ChangeClipboardChain(wnd, next_clipboard_wnd); | |||
+ clipboard_wnd = next_clipboard_wnd = 0; | |||
+ | |||
+ if (Fl::first_window()) | |||
+ fl_clipboard_notify_target(fl_xid(Fl::first_window())); | |||
+} | |||
+ | |||
//////////////////////////////////////////////////////////////// | |||
char fl_is_ime = 0; | |||
void fl_get_codepage() | |||
@@ -1327,6 +1359,27 @@ | |||
Fl::handle(FL_SCREEN_CONFIGURATION_CHANGED, NULL); | |||
return 0; | |||
+ case WM_CHANGECBCHAIN: | |||
+ if ((hWnd == clipboard_wnd) && | |||
+ (next_clipboard_wnd == (HWND)wParam)) { | |||
+ next_clipboard_wnd = (HWND)lParam; | |||
+ return 0; | |||
+ } | |||
+ break; | |||
+ | |||
+ case WM_DRAWCLIPBOARD: | |||
+ // When the clipboard moves between two FLTK windows, | |||
+ // fl_i_own_selection will temporarily be false as we are | |||
+ // processing this message. Hence the need to use fl_find(). | |||
+ if (!initial_clipboard && !fl_find(GetClipboardOwner())) | |||
+ fl_trigger_clipboard_notify(1); | |||
+ initial_clipboard = false; | |||
+ | |||
+ if (next_clipboard_wnd) | |||
+ SendMessage(next_clipboard_wnd, WM_DRAWCLIPBOARD, wParam, lParam); | |||
+ | |||
+ return 0; | |||
+ | |||
default: | |||
if (Fl::handle(0,0)) return 0; | |||
break; | |||
@@ -1685,6 +1738,8 @@ | |||
x->next = Fl_X::first; | |||
Fl_X::first = x; | |||
+ fl_clipboard_notify_target(x->xid); | |||
+ | |||
x->wait_for_expose = 1; | |||
if (fl_show_iconic) {showit = 0; fl_show_iconic = 0;} | |||
if (showit) { |
@@ -0,0 +1,645 @@ | |||
diff -ur fltk-1.3.2.org/FL/Fl_Window.H fltk-1.3.2/FL/Fl_Window.H | |||
--- fltk-1.3.2.org/FL/Fl_Window.H 2013-01-16 10:49:40.904228200 +0100 | |||
+++ fltk-1.3.2/FL/Fl_Window.H 2013-01-16 10:49:55.554353925 +0100 | |||
@@ -22,6 +22,10 @@ | |||
#ifndef Fl_Window_H | |||
#define Fl_Window_H | |||
+#ifdef WIN32 | |||
+#include <windows.h> | |||
+#endif | |||
+ | |||
#include "Fl_Group.H" | |||
#define FL_WINDOW 0xF0 ///< window type id all subclasses have type() >= this | |||
@@ -73,9 +77,19 @@ | |||
friend class Fl_X; | |||
Fl_X *i; // points at the system-specific stuff | |||
+ struct icon_data { | |||
+ const void *legacy_icon; | |||
+ Fl_RGB_Image **icons; | |||
+ int count; | |||
+#ifdef WIN32 | |||
+ HICON big_icon; | |||
+ HICON small_icon; | |||
+#endif | |||
+ }; | |||
+ | |||
const char* iconlabel_; | |||
char* xclass_; | |||
- const void* icon_; | |||
+ struct icon_data *icon_; | |||
// size_range stuff: | |||
int minw, minh, maxw, maxh; | |||
int dw, dh, aspect; | |||
@@ -121,6 +135,8 @@ | |||
*/ | |||
int force_position() const { return ((flags() & FORCE_POSITION)?1:0); } | |||
+ void free_icons(); | |||
+ | |||
public: | |||
/** | |||
@@ -350,6 +366,18 @@ | |||
static const char *default_xclass(); | |||
const char* xclass() const; | |||
void xclass(const char* c); | |||
+ | |||
+ static void default_icon(const Fl_RGB_Image*); | |||
+ static void default_icons(const Fl_RGB_Image*[], int); | |||
+ void icon(const Fl_RGB_Image*); | |||
+ void icons(const Fl_RGB_Image*[], int); | |||
+ | |||
+#ifdef WIN32 | |||
+ static void default_icons(HICON big_icon, HICON small_icon); | |||
+ void icons(HICON big_icon, HICON small_icon); | |||
+#endif | |||
+ | |||
+ /* for legacy compatibility */ | |||
const void* icon() const; | |||
void icon(const void * ic); | |||
diff -ur fltk-1.3.2.org/FL/mac.H fltk-1.3.2/FL/mac.H | |||
--- fltk-1.3.2.org/FL/mac.H 2013-01-16 10:49:40.904228200 +0100 | |||
+++ fltk-1.3.2/FL/mac.H 2013-01-16 10:49:55.554353925 +0100 | |||
@@ -120,6 +120,9 @@ | |||
void collapse(void); | |||
WindowRef window_ref(void); | |||
void set_key_window(void); | |||
+ // OS X doesn't have per window icons | |||
+ static void set_default_icons(const Fl_RGB_Image*[], int) {}; | |||
+ void set_icons() {}; | |||
int set_cursor(Fl_Cursor); | |||
int set_cursor(const Fl_RGB_Image*, int, int); | |||
static CGImageRef CGImage_from_window_rect(Fl_Window *win, int x, int y, int w, int h); | |||
diff -ur fltk-1.3.2.org/FL/win32.H fltk-1.3.2/FL/win32.H | |||
--- fltk-1.3.2.org/FL/win32.H 2013-01-16 10:49:40.904228200 +0100 | |||
+++ fltk-1.3.2/FL/win32.H 2013-01-16 10:49:55.555355617 +0100 | |||
@@ -84,6 +84,9 @@ | |||
void flush() {w->flush();} | |||
void set_minmax(LPMINMAXINFO minmax); | |||
void mapraise(); | |||
+ static void set_default_icons(const Fl_RGB_Image*[], int); | |||
+ static void set_default_icons(HICON, HICON); | |||
+ void set_icons(); | |||
int set_cursor(Fl_Cursor); | |||
int set_cursor(const Fl_RGB_Image*, int, int); | |||
static Fl_X* make(Fl_Window*); | |||
diff -ur fltk-1.3.2.org/FL/x.H fltk-1.3.2/FL/x.H | |||
--- fltk-1.3.2.org/FL/x.H 2013-01-16 10:49:40.904228200 +0100 | |||
+++ fltk-1.3.2/FL/x.H 2013-01-16 10:49:55.555355617 +0100 | |||
@@ -154,6 +154,8 @@ | |||
static Fl_X* i(const Fl_Window* wi) {return wi->i;} | |||
void setwindow(Fl_Window* wi) {w=wi; wi->i=this;} | |||
void sendxjunk(); | |||
+ static void set_default_icons(const Fl_RGB_Image*[], int); | |||
+ void set_icons(); | |||
int set_cursor(Fl_Cursor); | |||
int set_cursor(const Fl_RGB_Image*, int, int); | |||
static void make_xid(Fl_Window*,XVisualInfo* =fl_visual, Colormap=fl_colormap); | |||
diff -ur fltk-1.3.2.org/src/Fl.cxx fltk-1.3.2/src/Fl.cxx | |||
--- fltk-1.3.2.org/src/Fl.cxx 2013-01-16 10:49:40.895228113 +0100 | |||
+++ fltk-1.3.2/src/Fl.cxx 2013-01-16 10:49:55.556137979 +0100 | |||
@@ -1530,6 +1530,8 @@ | |||
if (xclass_) { | |||
free(xclass_); | |||
} | |||
+ free_icons(); | |||
+ delete icon_; | |||
} | |||
// FL_SHOW and FL_HIDE are called whenever the visibility of this widget | |||
diff -ur fltk-1.3.2.org/src/Fl_win32.cxx fltk-1.3.2/src/Fl_win32.cxx | |||
--- fltk-1.3.2.org/src/Fl_win32.cxx 2013-01-16 10:49:40.911227539 +0100 | |||
+++ fltk-1.3.2/src/Fl_win32.cxx 2013-01-16 10:49:55.556137979 +0100 | |||
@@ -1804,6 +1804,8 @@ | |||
); | |||
if (lab) free(lab); | |||
+ x->set_icons(); | |||
+ | |||
if (w->fullscreen_active()) { | |||
/* We need to make sure that the fullscreen is created on the | |||
default monitor, ie the desktop where the shortcut is located | |||
@@ -2034,71 +2036,19 @@ | |||
//////////////////////////////////////////////////////////////// | |||
-#ifndef IDC_HAND | |||
-# define IDC_HAND MAKEINTRESOURCE(32649) | |||
-#endif // !IDC_HAND | |||
- | |||
-int Fl_X::set_cursor(Fl_Cursor c) { | |||
- LPSTR n; | |||
- HCURSOR new_cursor; | |||
- | |||
- if (c == FL_CURSOR_NONE) | |||
- new_cursor = NULL; | |||
- else { | |||
- switch (c) { | |||
- case FL_CURSOR_ARROW: n = IDC_ARROW; break; | |||
- case FL_CURSOR_CROSS: n = IDC_CROSS; break; | |||
- case FL_CURSOR_WAIT: n = IDC_WAIT; break; | |||
- case FL_CURSOR_INSERT: n = IDC_IBEAM; break; | |||
- case FL_CURSOR_HAND: n = IDC_HAND; break; | |||
- case FL_CURSOR_HELP: n = IDC_HELP; break; | |||
- case FL_CURSOR_MOVE: n = IDC_SIZEALL; break; | |||
- case FL_CURSOR_N: | |||
- case FL_CURSOR_S: | |||
- // FIXME: Should probably have fallbacks for these instead | |||
- case FL_CURSOR_NS: n = IDC_SIZENS; break; | |||
- case FL_CURSOR_NE: | |||
- case FL_CURSOR_SW: | |||
- // FIXME: Dito. | |||
- case FL_CURSOR_NESW: n = IDC_SIZENESW; break; | |||
- case FL_CURSOR_E: | |||
- case FL_CURSOR_W: | |||
- // FIXME: Dito. | |||
- case FL_CURSOR_WE: n = IDC_SIZEWE; break; | |||
- case FL_CURSOR_SE: | |||
- case FL_CURSOR_NW: | |||
- // FIXME: Dito. | |||
- case FL_CURSOR_NWSE: n = IDC_SIZENWSE; break; | |||
- default: | |||
- return 0; | |||
- } | |||
- | |||
- new_cursor = LoadCursor(NULL, n); | |||
- if (new_cursor == NULL) | |||
- return 0; | |||
- } | |||
- | |||
- if ((cursor != NULL) && custom_cursor) | |||
- DestroyIcon(cursor); | |||
- | |||
- cursor = new_cursor; | |||
- custom_cursor = 0; | |||
- | |||
- SetCursor(cursor); | |||
- | |||
- return 1; | |||
-} | |||
- | |||
-int Fl_X::set_cursor(const Fl_RGB_Image *image, int hotx, int hoty) { | |||
+static HICON image_to_icon(const Fl_RGB_Image *image, bool is_icon=true, | |||
+ int hotx = 0, int hoty = 0) { | |||
BITMAPV5HEADER bi; | |||
HBITMAP bitmap, mask; | |||
DWORD *bits; | |||
- HCURSOR new_cursor; | |||
+ HICON icon; | |||
+ if (!is_icon) { | |||
if ((hotx < 0) || (hotx >= image->w())) | |||
- return 0; | |||
+ return NULL; | |||
if ((hoty < 0) || (hoty >= image->h())) | |||
- return 0; | |||
+ return NULL; | |||
+ } | |||
memset(&bi, 0, sizeof(BITMAPV5HEADER)); | |||
@@ -2120,7 +2070,7 @@ | |||
ReleaseDC(NULL, hdc); | |||
if (bits == NULL) | |||
- return 0; | |||
+ return NULL; | |||
const uchar *i = (const uchar*)*image->data(); | |||
for (int y = 0;y < image->h();y++) { | |||
@@ -2149,22 +2099,206 @@ | |||
mask = CreateBitmap(image->w(),image->h(),1,1,NULL); | |||
if (mask == NULL) { | |||
DeleteObject(bitmap); | |||
- return 0; | |||
+ return NULL; | |||
} | |||
ICONINFO ii; | |||
- ii.fIcon = FALSE; | |||
+ ii.fIcon = is_icon; | |||
ii.xHotspot = hotx; | |||
ii.yHotspot = hoty; | |||
ii.hbmMask = mask; | |||
ii.hbmColor = bitmap; | |||
- new_cursor = CreateIconIndirect(&ii); | |||
+ icon = CreateIconIndirect(&ii); | |||
DeleteObject(bitmap); | |||
DeleteObject(mask); | |||
+ if (icon == NULL) | |||
+ return NULL; | |||
+ | |||
+ return icon; | |||
+} | |||
+ | |||
+//////////////////////////////////////////////////////////////// | |||
+ | |||
+static HICON default_big_icon = NULL; | |||
+static HICON default_small_icon = NULL; | |||
+ | |||
+const Fl_RGB_Image *find_best_icon(int ideal_width, | |||
+ const Fl_RGB_Image *icons[], int count) { | |||
+ const Fl_RGB_Image *best; | |||
+ | |||
+ best = NULL; | |||
+ | |||
+ for (int i = 0;i < count;i++) { | |||
+ if (best == NULL) | |||
+ best = icons[i]; | |||
+ else { | |||
+ if (best->w() < ideal_width) { | |||
+ if (icons[i]->w() > best->w()) | |||
+ best = icons[i]; | |||
+ } else { | |||
+ if ((icons[i]->w() >= ideal_width) && | |||
+ (icons[i]->w() < best->w())) | |||
+ best = icons[i]; | |||
+ } | |||
+ } | |||
+ } | |||
+ | |||
+ return best; | |||
+} | |||
+ | |||
+void Fl_X::set_default_icons(const Fl_RGB_Image *icons[], int count) { | |||
+ const Fl_RGB_Image *best_big, *best_small; | |||
+ | |||
+ if (default_big_icon != NULL) | |||
+ DestroyIcon(default_big_icon); | |||
+ if (default_small_icon != NULL) | |||
+ DestroyIcon(default_small_icon); | |||
+ | |||
+ best_big = find_best_icon(GetSystemMetrics(SM_CXICON), icons, count); | |||
+ best_small = find_best_icon(GetSystemMetrics(SM_CXSMICON), icons, count); | |||
+ | |||
+ if (best_big != NULL) | |||
+ default_big_icon = image_to_icon(best_big); | |||
+ else | |||
+ default_big_icon = NULL; | |||
+ | |||
+ if (best_small != NULL) | |||
+ default_small_icon = image_to_icon(best_small); | |||
+ else | |||
+ default_small_icon = NULL; | |||
+} | |||
+ | |||
+void Fl_X::set_default_icons(HICON big_icon, HICON small_icon) { | |||
+ if (default_big_icon != NULL) | |||
+ DestroyIcon(default_big_icon); | |||
+ if (default_small_icon != NULL) | |||
+ DestroyIcon(default_small_icon); | |||
+ | |||
+ if (big_icon != NULL) | |||
+ default_big_icon = CopyIcon(big_icon); | |||
+ if (small_icon != NULL) | |||
+ default_small_icon = CopyIcon(small_icon); | |||
+} | |||
+ | |||
+void Fl_X::set_icons() { | |||
+ HICON big_icon, small_icon; | |||
+ | |||
+ big_icon = NULL; | |||
+ small_icon = NULL; | |||
+ | |||
+ if (w->icon_->count) { | |||
+ const Fl_RGB_Image *best_big, *best_small; | |||
+ | |||
+ best_big = find_best_icon(GetSystemMetrics(SM_CXICON), | |||
+ (const Fl_RGB_Image **)w->icon_->icons, | |||
+ w->icon_->count); | |||
+ best_small = find_best_icon(GetSystemMetrics(SM_CXSMICON), | |||
+ (const Fl_RGB_Image **)w->icon_->icons, | |||
+ w->icon_->count); | |||
+ | |||
+ if (best_big != NULL) | |||
+ big_icon = image_to_icon(best_big); | |||
+ if (best_small != NULL) | |||
+ small_icon = image_to_icon(best_small); | |||
+ } else { | |||
+ big_icon = default_big_icon; | |||
+ small_icon = default_small_icon; | |||
+ } | |||
+ | |||
+ if (big_icon != NULL) | |||
+ SendMessage(xid, WM_SETICON, ICON_BIG, (LPARAM)big_icon); | |||
+ if (small_icon != NULL) | |||
+ SendMessage(xid, WM_SETICON, ICON_SMALL, (LPARAM)small_icon); | |||
+ | |||
+ if (w->icon_->count) { | |||
+ if (big_icon != NULL) | |||
+ DestroyIcon(big_icon); | |||
+ if (small_icon != NULL) | |||
+ DestroyIcon(small_icon); | |||
+ } | |||
+} | |||
+ | |||
+void Fl_Window::default_icons(HICON big_icon, HICON small_icon) { | |||
+ Fl_X::set_default_icons(big_icon, small_icon); | |||
+} | |||
+ | |||
+void Fl_Window::icons(HICON big_icon, HICON small_icon) { | |||
+ free_icons(); | |||
+ | |||
+ if (big_icon != NULL) | |||
+ icon_->big_icon = CopyIcon(big_icon); | |||
+ if (small_icon != NULL) | |||
+ icon_->small_icon = CopyIcon(small_icon); | |||
+ | |||
+ if (i) | |||
+ i->set_icons(); | |||
+} | |||
+ | |||
+//////////////////////////////////////////////////////////////// | |||
+ | |||
+#ifndef IDC_HAND | |||
+# define IDC_HAND MAKEINTRESOURCE(32649) | |||
+#endif // !IDC_HAND | |||
+ | |||
+int Fl_X::set_cursor(Fl_Cursor c) { | |||
+ LPSTR n; | |||
+ HCURSOR new_cursor; | |||
+ | |||
+ if (c == FL_CURSOR_NONE) | |||
+ new_cursor = NULL; | |||
+ else { | |||
+ switch (c) { | |||
+ case FL_CURSOR_ARROW: n = IDC_ARROW; break; | |||
+ case FL_CURSOR_CROSS: n = IDC_CROSS; break; | |||
+ case FL_CURSOR_WAIT: n = IDC_WAIT; break; | |||
+ case FL_CURSOR_INSERT: n = IDC_IBEAM; break; | |||
+ case FL_CURSOR_HAND: n = IDC_HAND; break; | |||
+ case FL_CURSOR_HELP: n = IDC_HELP; break; | |||
+ case FL_CURSOR_MOVE: n = IDC_SIZEALL; break; | |||
+ case FL_CURSOR_N: | |||
+ case FL_CURSOR_S: | |||
+ // FIXME: Should probably have fallbacks for these instead | |||
+ case FL_CURSOR_NS: n = IDC_SIZENS; break; | |||
+ case FL_CURSOR_NE: | |||
+ case FL_CURSOR_SW: | |||
+ // FIXME: Dito. | |||
+ case FL_CURSOR_NESW: n = IDC_SIZENESW; break; | |||
+ case FL_CURSOR_E: | |||
+ case FL_CURSOR_W: | |||
+ // FIXME: Dito. | |||
+ case FL_CURSOR_WE: n = IDC_SIZEWE; break; | |||
+ case FL_CURSOR_SE: | |||
+ case FL_CURSOR_NW: | |||
+ // FIXME: Dito. | |||
+ case FL_CURSOR_NWSE: n = IDC_SIZENWSE; break; | |||
+ default: | |||
+ return 0; | |||
+ } | |||
+ | |||
+ new_cursor = LoadCursor(NULL, n); | |||
+ if (new_cursor == NULL) | |||
+ return 0; | |||
+ } | |||
+ | |||
+ if ((cursor != NULL) && custom_cursor) | |||
+ DestroyIcon(cursor); | |||
+ | |||
+ cursor = new_cursor; | |||
+ custom_cursor = 0; | |||
+ | |||
+ SetCursor(cursor); | |||
+ | |||
+ return 1; | |||
+} | |||
+ | |||
+int Fl_X::set_cursor(const Fl_RGB_Image *image, int hotx, int hoty) { | |||
+ HCURSOR new_cursor; | |||
+ | |||
+ new_cursor = image_to_icon(image, false, hotx, hoty); | |||
if (new_cursor == NULL) | |||
return 0; | |||
diff -ur fltk-1.3.2.org/src/Fl_Window.cxx fltk-1.3.2/src/Fl_Window.cxx | |||
--- fltk-1.3.2.org/src/Fl_Window.cxx 2013-01-16 10:49:40.908130903 +0100 | |||
+++ fltk-1.3.2/src/Fl_Window.cxx 2013-01-16 10:49:55.557353865 +0100 | |||
@@ -23,6 +23,7 @@ | |||
#include <config.h> | |||
#include <FL/Fl.H> | |||
#include <FL/x.H> | |||
+#include <FL/Fl_RGB_Image.H> | |||
#include <FL/Fl_Window.H> | |||
#include <stdlib.h> | |||
#include "flstring.h" | |||
@@ -45,7 +46,8 @@ | |||
} | |||
i = 0; | |||
xclass_ = 0; | |||
- icon_ = 0; | |||
+ icon_ = new icon_data; | |||
+ memset(icon_, 0, sizeof(*icon_)); | |||
iconlabel_ = 0; | |||
resizable(0); | |||
size_range_set = 0; | |||
@@ -264,16 +266,68 @@ | |||
} | |||
} | |||
+void Fl_Window::default_icon(const Fl_RGB_Image *icon) { | |||
+ default_icons(&icon, 1); | |||
+} | |||
+ | |||
+void Fl_Window::default_icons(const Fl_RGB_Image **icons, int count) { | |||
+ Fl_X::set_default_icons(icons, count); | |||
+} | |||
+ | |||
+void Fl_Window::icon(const Fl_RGB_Image *icon) { | |||
+ icons(&icon, 1); | |||
+} | |||
+ | |||
+void Fl_Window::icons(const Fl_RGB_Image **icons, int count) { | |||
+ free_icons(); | |||
+ | |||
+ if (count > 0) { | |||
+ icon_->icons = new Fl_RGB_Image*[count]; | |||
+ icon_->count = count; | |||
+ // FIXME: Fl_RGB_Image lacks const modifiers on methods | |||
+ for (int i = 0;i < count;i++) | |||
+ icon_->icons[i] = (Fl_RGB_Image*)((Fl_RGB_Image*)icons[i])->copy(); | |||
+ } | |||
+ | |||
+ if (i) | |||
+ i->set_icons(); | |||
+} | |||
+ | |||
/** Gets the current icon window target dependent data. */ | |||
const void *Fl_Window::icon() const { | |||
- return icon_; | |||
+ return icon_->legacy_icon; | |||
} | |||
/** Sets the current icon window target dependent data. */ | |||
void Fl_Window::icon(const void * ic) { | |||
- icon_ = ic; | |||
+ free_icons(); | |||
+ icon_->legacy_icon = ic; | |||
} | |||
+void Fl_Window::free_icons() { | |||
+ int i; | |||
+ | |||
+ icon_->legacy_icon = 0L; | |||
+ | |||
+ if (icon_->icons) { | |||
+ for (i = 0;i < icon_->count;i++) | |||
+ delete icon_->icons[i]; | |||
+ delete [] icon_->icons; | |||
+ icon_->icons = 0L; | |||
+ } | |||
+ | |||
+ icon_->count = 0; | |||
+ | |||
+#ifdef WIN32 | |||
+ if (icon_->big_icon) | |||
+ DestroyIcon(icon_->big_icon); | |||
+ if (icon_->small_icon) | |||
+ DestroyIcon(icon_->small_icon); | |||
+ | |||
+ icon_->big_icon = NULL; | |||
+ icon_->small_icon = NULL; | |||
+#endif | |||
+} | |||
// | |||
// End of "$Id: Fl_Window.cxx 9706 2012-11-06 20:46:14Z matt $". | |||
diff -ur fltk-1.3.2.org/src/Fl_x.cxx fltk-1.3.2/src/Fl_x.cxx | |||
--- fltk-1.3.2.org/src/Fl_x.cxx 2013-01-16 10:49:40.912227213 +0100 | |||
+++ fltk-1.3.2/src/Fl_x.cxx 2013-01-16 10:49:55.558137113 +0100 | |||
@@ -345,6 +345,7 @@ | |||
Atom fl_NET_WM_STATE; | |||
Atom fl_NET_WM_STATE_FULLSCREEN; | |||
Atom fl_NET_WORKAREA; | |||
+Atom fl_NET_WM_ICON; | |||
/* | |||
X defines 32-bit-entities to have a format value of max. 32, | |||
@@ -709,6 +710,7 @@ | |||
fl_NET_WM_STATE = XInternAtom(d, "_NET_WM_STATE", 0); | |||
fl_NET_WM_STATE_FULLSCREEN = XInternAtom(d, "_NET_WM_STATE_FULLSCREEN", 0); | |||
fl_NET_WORKAREA = XInternAtom(d, "_NET_WORKAREA", 0); | |||
+ fl_NET_WM_ICON = XInternAtom(d, "_NET_WM_ICON", 0); | |||
if (sizeof(Atom) < 4) | |||
atom_bits = sizeof(Atom) * 8; | |||
@@ -2138,12 +2140,14 @@ | |||
fl_show_iconic = 0; | |||
showit = 0; | |||
} | |||
- if (win->icon()) { | |||
- hints->icon_pixmap = (Pixmap)win->icon(); | |||
+ if (win->icon_->legacy_icon) { | |||
+ hints->icon_pixmap = (Pixmap)win->icon_->legacy_icon; | |||
hints->flags |= IconPixmapHint; | |||
} | |||
XSetWMHints(fl_display, xp->xid, hints); | |||
XFree(hints); | |||
+ | |||
+ xp->set_icons(); | |||
} | |||
// set the window type for menu and tooltip windows to avoid animations (compiz) | |||
@@ -2263,6 +2267,93 @@ | |||
//////////////////////////////////////////////////////////////// | |||
+static unsigned long *default_net_wm_icons = 0L; | |||
+static size_t default_net_wm_icons_size = 0; | |||
+ | |||
+void icons_to_property(const Fl_RGB_Image *icons[], int count, | |||
+ unsigned long **property, size_t *len) { | |||
+ size_t sz; | |||
+ unsigned long *data; | |||
+ | |||
+ sz = 0; | |||
+ for (int i = 0;i < count;i++) | |||
+ sz += 2 + icons[i]->w() * icons[i]->h(); | |||
+ | |||
+ // FIXME: Might want to sort the icons | |||
+ | |||
+ *property = data = new unsigned long[sz]; | |||
+ *len = sz; | |||
+ | |||
+ for (int i = 0;i < count;i++) { | |||
+ const Fl_RGB_Image *image; | |||
+ | |||
+ image = icons[i]; | |||
+ | |||
+ data[0] = image->w(); | |||
+ data[1] = image->h(); | |||
+ data += 2; | |||
+ | |||
+ const uchar *in = (const uchar*)*image->data(); | |||
+ for (int y = 0;y < image->h();y++) { | |||
+ for (int x = 0;x < image->w();x++) { | |||
+ switch (image->d()) { | |||
+ case 1: | |||
+ *data = ( 0xff<<24) | (in[0]<<16) | (in[0]<<8) | in[0]; | |||
+ break; | |||
+ case 2: | |||
+ *data = (in[1]<<24) | (in[0]<<16) | (in[0]<<8) | in[0]; | |||
+ break; | |||
+ case 3: | |||
+ *data = ( 0xff<<24) | (in[0]<<16) | (in[1]<<8) | in[2]; | |||
+ break; | |||
+ case 4: | |||
+ *data = (in[3]<<24) | (in[0]<<16) | (in[1]<<8) | in[2]; | |||
+ break; | |||
+ } | |||
+ in += image->d(); | |||
+ data++; | |||
+ } | |||
+ in += image->ld(); | |||
+ } | |||
+ } | |||
+} | |||
+ | |||
+void Fl_X::set_default_icons(const Fl_RGB_Image *icons[], int count) { | |||
+ if (default_net_wm_icons) { | |||
+ delete [] default_net_wm_icons; | |||
+ default_net_wm_icons = 0L; | |||
+ default_net_wm_icons_size = 0; | |||
+ } | |||
+ | |||
+ if (count > 0) | |||
+ icons_to_property(icons, count, | |||
+ &default_net_wm_icons, &default_net_wm_icons_size); | |||
+} | |||
+ | |||
+void Fl_X::set_icons() { | |||
+ unsigned long *net_wm_icons; | |||
+ size_t net_wm_icons_size; | |||
+ | |||
+ if (w->icon_->count) { | |||
+ icons_to_property((const Fl_RGB_Image **)w->icon_->icons, w->icon_->count, | |||
+ &net_wm_icons, &net_wm_icons_size); | |||
+ } else { | |||
+ net_wm_icons = default_net_wm_icons; | |||
+ net_wm_icons_size = default_net_wm_icons_size; | |||
+ } | |||
+ | |||
+ XChangeProperty (fl_display, xid, fl_NET_WM_ICON, XA_CARDINAL, 32, | |||
+ PropModeReplace, (unsigned char*) net_wm_icons, net_wm_icons_size); | |||
+ | |||
+ if (w->icon_->count) { | |||
+ delete [] net_wm_icons; | |||
+ net_wm_icons = 0L; | |||
+ net_wm_icons_size = 0; | |||
+ } | |||
+} | |||
+ | |||
+//////////////////////////////////////////////////////////////// | |||
+ | |||
int Fl_X::set_cursor(Fl_Cursor c) { | |||
unsigned int shape; | |||
Cursor xc; |
@@ -0,0 +1,135 @@ | |||
diff -ur fltk-1.3.0r9110.org/src/Fl_win32.cxx fltk-1.3.0r9110/src/Fl_win32.cxx | |||
--- fltk-1.3.0r9110.org/src/Fl_win32.cxx 2012-06-17 19:42:02.169422400 +0200 | |||
+++ fltk-1.3.0r9110/src/Fl_win32.cxx 2012-06-17 19:43:38.286031455 +0200 | |||
@@ -543,6 +543,37 @@ | |||
const char* GetValue() const { return(out); } | |||
}; | |||
+void fl_update_clipboard(void) { | |||
+ Fl_Window *w1 = Fl::first_window(); | |||
+ if (!w1) | |||
+ return; | |||
+ | |||
+ HWND hwnd = fl_xid(w1); | |||
+ | |||
+ if (!OpenClipboard(hwnd)) | |||
+ return; | |||
+ | |||
+ EmptyClipboard(); | |||
+ | |||
+ int utf16_len = fl_utf8toUtf16(fl_selection_buffer[1], | |||
+ fl_selection_length[1], 0, 0); | |||
+ | |||
+ HGLOBAL hMem = GlobalAlloc(GHND, utf16_len * 2 + 2); // moveable and zero'ed mem alloc. | |||
+ LPVOID memLock = GlobalLock(hMem); | |||
+ | |||
+ fl_utf8toUtf16(fl_selection_buffer[1], fl_selection_length[1], | |||
+ (unsigned short*) memLock, utf16_len + 1); | |||
+ | |||
+ GlobalUnlock(hMem); | |||
+ SetClipboardData(CF_UNICODETEXT, hMem); | |||
+ | |||
+ CloseClipboard(); | |||
+ | |||
+ // In case Windows managed to lob of a WM_DESTROYCLIPBOARD during | |||
+ // the above. | |||
+ fl_i_own_selection[1] = 1; | |||
+} | |||
+ | |||
// call this when you create a selection: | |||
void Fl::copy(const char *stuff, int len, int clipboard) { | |||
if (!stuff || len<0) return; | |||
@@ -560,25 +591,9 @@ | |||
memcpy(fl_selection_buffer[clipboard], stuff, len); | |||
fl_selection_buffer[clipboard][len] = 0; // needed for direct paste | |||
fl_selection_length[clipboard] = len; | |||
- if (clipboard) { | |||
- // set up for "delayed rendering": | |||
- if (OpenClipboard(NULL)) { | |||
- // if the system clipboard works, use it | |||
- int utf16_len = fl_utf8toUtf16(fl_selection_buffer[clipboard], fl_selection_length[clipboard], 0, 0); | |||
- EmptyClipboard(); | |||
- HGLOBAL hMem = GlobalAlloc(GHND, utf16_len * 2 + 2); // moveable and zero'ed mem alloc. | |||
- LPVOID memLock = GlobalLock(hMem); | |||
- fl_utf8toUtf16(fl_selection_buffer[clipboard], fl_selection_length[clipboard], (unsigned short*) memLock, utf16_len + 1); | |||
- GlobalUnlock(hMem); | |||
- SetClipboardData(CF_UNICODETEXT, hMem); | |||
- CloseClipboard(); | |||
- GlobalFree(hMem); | |||
- fl_i_own_selection[clipboard] = 0; | |||
- } else { | |||
- // only if it fails, instruct paste() to use the internal buffers | |||
- fl_i_own_selection[clipboard] = 1; | |||
- } | |||
- } | |||
+ fl_i_own_selection[clipboard] = 1; | |||
+ if (clipboard) | |||
+ fl_update_clipboard(); | |||
} | |||
// Call this when a "paste" operation happens: | |||
@@ -1307,33 +1322,6 @@ | |||
fl_i_own_selection[1] = 0; | |||
return 1; | |||
- case WM_RENDERALLFORMATS: | |||
- fl_i_own_selection[1] = 0; | |||
- // Windoze seems unhappy unless I do these two steps. Documentation | |||
- // seems to vary on whether opening the clipboard is necessary or | |||
- // is in fact wrong: | |||
- CloseClipboard(); | |||
- OpenClipboard(NULL); | |||
- // fall through... | |||
- case WM_RENDERFORMAT: { | |||
- HANDLE h; | |||
- | |||
-// int l = fl_utf_nb_char((unsigned char*)fl_selection_buffer[1], fl_selection_length[1]); | |||
- int l = fl_utf8toUtf16(fl_selection_buffer[1], fl_selection_length[1], NULL, 0); // Pass NULL buffer to query length required | |||
- h = GlobalAlloc(GHND, (l+1) * sizeof(unsigned short)); | |||
- if (h) { | |||
- unsigned short *g = (unsigned short*) GlobalLock(h); | |||
-// fl_utf2unicode((unsigned char *)fl_selection_buffer[1], fl_selection_length[1], (xchar*)g); | |||
- l = fl_utf8toUtf16(fl_selection_buffer[1], fl_selection_length[1], g, (l+1)); | |||
- g[l] = 0; | |||
- GlobalUnlock(h); | |||
- SetClipboardData(CF_UNICODETEXT, h); | |||
- } | |||
- | |||
- // Windoze also seems unhappy if I don't do this. Documentation very | |||
- // unclear on what is correct: | |||
- if (fl_msg.message == WM_RENDERALLFORMATS) CloseClipboard(); | |||
- return 1;} | |||
case WM_DISPLAYCHANGE: // occurs when screen configuration (number, position) changes | |||
Fl::call_screen_init(); | |||
Fl::handle(FL_SCREEN_CONFIGURATION_CHANGED, NULL); | |||
diff -ur fltk-1.3.0r9110.org/src/Fl.cxx fltk-1.3.0r9110/src/Fl.cxx | |||
--- fltk-1.3.0r9110.org/src/Fl.cxx 2012-06-17 19:42:02.173422595 +0200 | |||
+++ fltk-1.3.0r9110/src/Fl.cxx 2012-06-17 19:42:02.317429497 +0200 | |||
@@ -1420,7 +1420,9 @@ | |||
//////////////////////////////////////////////////////////////// | |||
// hide() destroys the X window, it does not do unmap! | |||
-#if !defined(WIN32) && USE_XFT | |||
+#if defined(WIN32) | |||
+extern void fl_update_clipboard(void); | |||
+#elif USE_XFT | |||
extern void fl_destroy_xft_draw(Window); | |||
#endif | |||
@@ -1467,14 +1469,8 @@ | |||
#if defined(WIN32) | |||
// this little trick keeps the current clipboard alive, even if we are about | |||
// to destroy the window that owns the selection. | |||
- if (GetClipboardOwner()==ip->xid) { | |||
- Fl_Window *w1 = Fl::first_window(); | |||
- if (w1 && OpenClipboard(fl_xid(w1))) { | |||
- EmptyClipboard(); | |||
- SetClipboardData(CF_TEXT, NULL); | |||
- CloseClipboard(); | |||
- } | |||
- } | |||
+ if (GetClipboardOwner()==ip->xid) | |||
+ fl_update_clipboard(); | |||
// Send a message to myself so that I'll get out of the event loop... | |||
PostMessage(ip->xid, WM_APP, 0, 0); | |||
if (ip->private_dc) fl_release_dc(ip->xid, ip->private_dc); |
@@ -0,0 +1,468 @@ | |||
diff -urp fltk-1.3.2.org/FL/Fl_Window.H fltk-1.3.2/FL/Fl_Window.H | |||
--- fltk-1.3.2.org/FL/Fl_Window.H 2013-01-16 10:52:33.017228122 +0100 | |||
+++ fltk-1.3.2/FL/Fl_Window.H 2013-01-16 10:52:47.876478968 +0100 | |||
@@ -54,7 +54,7 @@ class Fl_RGB_Image; | |||
class FL_EXPORT Fl_Window : public Fl_Group { | |||
static char *default_xclass_; | |||
- // Note: we must use separate statements for each of the following 4 variables, | |||
+ // Note: we must use separate statements for each of the following 8 variables, | |||
// with the static attribute, otherwise MS VC++ 2008/2010 complains :-( | |||
// AlbrechtS 04/2012 | |||
#if FLTK_ABI_VERSION < 10301 | |||
@@ -73,6 +73,22 @@ class FL_EXPORT Fl_Window : public Fl_Gr | |||
static // when these members are static, ABI compatibility with 1.3.0 is respected | |||
#endif | |||
int no_fullscreen_h; | |||
+#if FLTK_ABI_VERSION < 10302 | |||
+ static // when these members are static, ABI compatibility with 1.3.0 is respected | |||
+#endif | |||
+ int fullscreen_screen_top; | |||
+#if FLTK_ABI_VERSION < 10302 | |||
+ static // when these members are static, ABI compatibility with 1.3.0 is respected | |||
+#endif | |||
+ int fullscreen_screen_bottom; | |||
+#if FLTK_ABI_VERSION < 10302 | |||
+ static // when these members are static, ABI compatibility with 1.3.0 is respected | |||
+#endif | |||
+ int fullscreen_screen_left; | |||
+#if FLTK_ABI_VERSION < 10302 | |||
+ static // when these members are static, ABI compatibility with 1.3.0 is respected | |||
+#endif | |||
+ int fullscreen_screen_right; | |||
friend class Fl_X; | |||
Fl_X *i; // points at the system-specific stuff | |||
@@ -430,13 +446,15 @@ public: | |||
*/ | |||
void show(int argc, char **argv); | |||
/** | |||
- Makes the window completely fill the screen, without any window | |||
- manager border visible. You must use fullscreen_off() to undo | |||
- this. | |||
+ Makes the window completely fill one or more screens, without any | |||
+ window manager border visible. You must use fullscreen_off() to | |||
+ undo this. | |||
\note On some platforms, this can result in the keyboard being | |||
grabbed. The window may also be recreated, meaning hide() and | |||
show() will be called. | |||
+ | |||
+ \see void Fl_Window::fullscreen_screens() | |||
*/ | |||
void fullscreen(); | |||
/** | |||
@@ -453,6 +471,17 @@ public: | |||
*/ | |||
unsigned int fullscreen_active() const { return flags() & FULLSCREEN; } | |||
/** | |||
+ Sets which screens should be used when this window is in fullscreen | |||
+ mode. The window will be resized to the top of the screen with index | |||
+ \p top, the bottom of the screen with index \p bottom, etc. | |||
+ | |||
+ If this method is never called, or if any argument is < 0, then the | |||
+ window will be resized to fill the screen it is currently on. | |||
+ | |||
+ \see void Fl_Window::fullscreen() | |||
+ */ | |||
+ void fullscreen_screens(int top, int bottom, int left, int right); | |||
+ /** | |||
Iconifies the window. If you call this when shown() is false | |||
it will show() it as an icon. If the window is already | |||
iconified this does nothing. | |||
diff -urp fltk-1.3.2.org/FL/win32.H fltk-1.3.2/FL/win32.H | |||
--- fltk-1.3.2.org/FL/win32.H 2013-01-16 10:52:33.017228122 +0100 | |||
+++ fltk-1.3.2/FL/win32.H 2013-01-16 10:52:47.876478968 +0100 | |||
@@ -80,6 +80,7 @@ public: | |||
static Fl_X* i(const Fl_Window* w) {return w->i;} | |||
static int fake_X_wm(const Fl_Window* w,int &X, int &Y, | |||
int &bt,int &bx,int &by); | |||
+ void make_fullscreen(int X, int Y, int W, int H); | |||
void setwindow(Fl_Window* wi) {w=wi; wi->i=this;} | |||
void flush() {w->flush();} | |||
void set_minmax(LPMINMAXINFO minmax); | |||
diff -urp fltk-1.3.2.org/src/Fl_cocoa.mm fltk-1.3.2/src/Fl_cocoa.mm | |||
--- fltk-1.3.2.org/src/Fl_cocoa.mm 2013-01-16 10:52:33.014229574 +0100 | |||
+++ fltk-1.3.2/src/Fl_cocoa.mm 2013-01-16 10:52:47.877480606 +0100 | |||
@@ -2438,9 +2438,32 @@ void Fl_X::make(Fl_Window* w) | |||
NSRect crect; | |||
if (w->fullscreen_active()) { | |||
- int sx, sy, sw, sh; | |||
- Fl::screen_xywh(sx, sy, sw, sh, w->x(), w->y(), w->w(), w->h()); | |||
- w->resize(sx, sy, sw, sh); | |||
+ int top, bottom, left, right; | |||
+ int sx, sy, sw, sh, X, Y, W, H; | |||
+ | |||
+ top = w->fullscreen_screen_top; | |||
+ bottom = w->fullscreen_screen_bottom; | |||
+ left = w->fullscreen_screen_left; | |||
+ right = w->fullscreen_screen_right; | |||
+ | |||
+ if ((top < 0) || (bottom < 0) || (left < 0) || (right < 0)) { | |||
+ top = Fl::screen_num(w->x(), w->y(), w->w(), w->h()); | |||
+ bottom = top; | |||
+ left = top; | |||
+ right = top; | |||
+ } | |||
+ | |||
+ Fl::screen_xywh(sx, sy, sw, sh, top); | |||
+ Y = sy; | |||
+ Fl::screen_xywh(sx, sy, sw, sh, bottom); | |||
+ H = sy + sh - Y; | |||
+ Fl::screen_xywh(sx, sy, sw, sh, left); | |||
+ X = sx; | |||
+ Fl::screen_xywh(sx, sy, sw, sh, right); | |||
+ W = sx + sw - X; | |||
+ | |||
+ w->resize(X, Y, W, H); | |||
+ | |||
winstyle = NSBorderlessWindowMask; | |||
winlevel = NSStatusWindowLevel; | |||
} | |||
diff -urp fltk-1.3.2.org/src/Fl_win32.cxx fltk-1.3.2/src/Fl_win32.cxx | |||
--- fltk-1.3.2.org/src/Fl_win32.cxx 2013-01-16 10:52:33.019230734 +0100 | |||
+++ fltk-1.3.2/src/Fl_win32.cxx 2013-01-16 10:52:47.878480504 +0100 | |||
@@ -1493,7 +1493,6 @@ int Fl_X::fake_X_wm(const Fl_Window* w,i | |||
Y+=yoff; | |||
if (w->fullscreen_active()) { | |||
- X = Y = 0; | |||
bx = by = bt = 0; | |||
} | |||
@@ -1547,19 +1546,42 @@ void Fl_Window::resize(int X,int Y,int W | |||
} | |||
} | |||
-static void make_fullscreen(Fl_Window *w, Window xid, int X, int Y, int W, int H) { | |||
+void Fl_X::make_fullscreen(int X, int Y, int W, int H) { | |||
+ int top, bottom, left, right; | |||
int sx, sy, sw, sh; | |||
- Fl::screen_xywh(sx, sy, sw, sh, X, Y, W, H); | |||
+ | |||
+ top = w->fullscreen_screen_top; | |||
+ bottom = w->fullscreen_screen_bottom; | |||
+ left = w->fullscreen_screen_left; | |||
+ right = w->fullscreen_screen_right; | |||
+ | |||
+ if ((top < 0) || (bottom < 0) || (left < 0) || (right < 0)) { | |||
+ top = Fl::screen_num(X, Y, W, H); | |||
+ bottom = top; | |||
+ left = top; | |||
+ right = top; | |||
+ } | |||
+ | |||
+ Fl::screen_xywh(sx, sy, sw, sh, top); | |||
+ Y = sy; | |||
+ Fl::screen_xywh(sx, sy, sw, sh, bottom); | |||
+ H = sy + sh - Y; | |||
+ Fl::screen_xywh(sx, sy, sw, sh, left); | |||
+ X = sx; | |||
+ Fl::screen_xywh(sx, sy, sw, sh, right); | |||
+ W = sx + sw - X; | |||
+ | |||
DWORD flags = GetWindowLong(xid, GWL_STYLE); | |||
flags = flags & ~(WS_THICKFRAME|WS_CAPTION); | |||
SetWindowLong(xid, GWL_STYLE, flags); | |||
+ | |||
// SWP_NOSENDCHANGING is so that we can override size limits | |||
- SetWindowPos(xid, HWND_TOP, sx, sy, sw, sh, SWP_NOSENDCHANGING | SWP_FRAMECHANGED); | |||
+ SetWindowPos(xid, HWND_TOP, X, Y, W, H, SWP_NOSENDCHANGING | SWP_FRAMECHANGED); | |||
} | |||
void Fl_Window::fullscreen_x() { | |||
_set_fullscreen(); | |||
- make_fullscreen(this, fl_xid(this), x(), y(), w(), h()); | |||
+ i->make_fullscreen(x(), y(), w(), h()); | |||
Fl::handle(FL_FULLSCREEN, this); | |||
} | |||
@@ -1814,8 +1836,8 @@ Fl_X* Fl_X::make(Fl_Window* w) { | |||
monitor the window was placed on. */ | |||
RECT rect; | |||
GetWindowRect(x->xid, &rect); | |||
- make_fullscreen(w, x->xid, rect.left, rect.top, | |||
- rect.right - rect.left, rect.bottom - rect.top); | |||
+ x->make_fullscreen(rect.left, rect.top, | |||
+ rect.right - rect.left, rect.bottom - rect.top); | |||
} | |||
x->next = Fl_X::first; | |||
diff -urp fltk-1.3.2.org/src/Fl_Window_fullscreen.cxx fltk-1.3.2/src/Fl_Window_fullscreen.cxx | |||
--- fltk-1.3.2.org/src/Fl_Window_fullscreen.cxx 2012-11-06 21:46:14.000000000 +0100 | |||
+++ fltk-1.3.2/src/Fl_Window_fullscreen.cxx 2013-01-16 10:52:47.879480608 +0100 | |||
@@ -36,6 +36,10 @@ int Fl_Window::no_fullscreen_x = 0; | |||
int Fl_Window::no_fullscreen_y = 0; | |||
int Fl_Window::no_fullscreen_w = 0; | |||
int Fl_Window::no_fullscreen_h = 0; | |||
+int Fl_Window::fullscreen_screen_top = -1; | |||
+int Fl_Window::fullscreen_screen_bottom = -1; | |||
+int Fl_Window::fullscreen_screen_left = -1; | |||
+int Fl_Window::fullscreen_screen_right = -1; | |||
#endif | |||
void Fl_Window::border(int b) { | |||
@@ -95,6 +99,23 @@ void Fl_Window::fullscreen_off() { | |||
fullscreen_off(no_fullscreen_x, no_fullscreen_y, no_fullscreen_w, no_fullscreen_h); | |||
} | |||
+void Fl_Window::fullscreen_screens(int top, int bottom, int left, int right) { | |||
+ if ((top < 0) || (bottom < 0) || (left < 0) || (right < 0)) { | |||
+ fullscreen_screen_top = -1; | |||
+ fullscreen_screen_bottom = -1; | |||
+ fullscreen_screen_left = -1; | |||
+ fullscreen_screen_right = -1; | |||
+ } else { | |||
+ fullscreen_screen_top = top; | |||
+ fullscreen_screen_bottom = bottom; | |||
+ fullscreen_screen_left = left; | |||
+ fullscreen_screen_right = right; | |||
+ } | |||
+ | |||
+ if (shown() && (flags() & Fl_Widget::FULLSCREEN)) | |||
+ fullscreen_x(); | |||
+} | |||
+ | |||
// | |||
// End of "$Id: Fl_Window_fullscreen.cxx 9706 2012-11-06 20:46:14Z matt $". | |||
diff -urp fltk-1.3.2.org/src/Fl_x.cxx fltk-1.3.2/src/Fl_x.cxx | |||
--- fltk-1.3.2.org/src/Fl_x.cxx 2013-01-16 10:52:33.020228202 +0100 | |||
+++ fltk-1.3.2/src/Fl_x.cxx 2013-01-16 10:52:47.880480556 +0100 | |||
@@ -344,6 +344,7 @@ Atom fl_NET_WM_ICON_NAME; // utf8 aware | |||
Atom fl_NET_SUPPORTING_WM_CHECK; | |||
Atom fl_NET_WM_STATE; | |||
Atom fl_NET_WM_STATE_FULLSCREEN; | |||
+Atom fl_NET_WM_FULLSCREEN_MONITORS; | |||
Atom fl_NET_WORKAREA; | |||
Atom fl_NET_WM_ICON; | |||
@@ -709,6 +710,7 @@ void fl_open_display(Display* d) { | |||
fl_NET_SUPPORTING_WM_CHECK = XInternAtom(d, "_NET_SUPPORTING_WM_CHECK", 0); | |||
fl_NET_WM_STATE = XInternAtom(d, "_NET_WM_STATE", 0); | |||
fl_NET_WM_STATE_FULLSCREEN = XInternAtom(d, "_NET_WM_STATE_FULLSCREEN", 0); | |||
+ fl_NET_WM_FULLSCREEN_MONITORS = XInternAtom(d, "_NET_WM_FULLSCREEN_MONITORS", 0); | |||
fl_NET_WORKAREA = XInternAtom(d, "_NET_WORKAREA", 0); | |||
fl_NET_WM_ICON = XInternAtom(d, "_NET_WM_ICON", 0); | |||
@@ -1872,22 +1874,30 @@ void Fl_Window::resize(int X,int Y,int W | |||
#define _NET_WM_STATE_ADD 1 /* add/set property */ | |||
#define _NET_WM_STATE_TOGGLE 2 /* toggle property */ | |||
-static void send_wm_state_event(Window wnd, int add, Atom prop) { | |||
+static void send_wm_event(Window wnd, Atom message, | |||
+ unsigned long d0, unsigned long d1=0, | |||
+ unsigned long d2=0, unsigned long d3=0, | |||
+ unsigned long d4=0) { | |||
XEvent e; | |||
e.xany.type = ClientMessage; | |||
e.xany.window = wnd; | |||
- e.xclient.message_type = fl_NET_WM_STATE; | |||
+ e.xclient.message_type = message; | |||
e.xclient.format = 32; | |||
- e.xclient.data.l[0] = add ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE; | |||
- e.xclient.data.l[1] = prop; | |||
- e.xclient.data.l[2] = 0; | |||
- e.xclient.data.l[3] = 0; | |||
- e.xclient.data.l[4] = 0; | |||
+ e.xclient.data.l[0] = d0; | |||
+ e.xclient.data.l[1] = d1; | |||
+ e.xclient.data.l[2] = d2; | |||
+ e.xclient.data.l[3] = d3; | |||
+ e.xclient.data.l[4] = d4; | |||
XSendEvent(fl_display, RootWindow(fl_display, fl_screen), | |||
0, SubstructureNotifyMask | SubstructureRedirectMask, | |||
&e); | |||
} | |||
+static void send_wm_state_event(Window wnd, int add, Atom prop) { | |||
+ send_wm_event(wnd, fl_NET_WM_STATE, | |||
+ add ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE, prop); | |||
+} | |||
+ | |||
int Fl_X::ewmh_supported() { | |||
static int result = -1; | |||
@@ -1911,6 +1921,22 @@ int Fl_X::ewmh_supported() { | |||
/* Change an existing window to fullscreen */ | |||
void Fl_Window::fullscreen_x() { | |||
if (Fl_X::ewmh_supported()) { | |||
+ int top, bottom, left, right; | |||
+ | |||
+ top = fullscreen_screen_top; | |||
+ bottom = fullscreen_screen_bottom; | |||
+ left = fullscreen_screen_left; | |||
+ right = fullscreen_screen_right; | |||
+ | |||
+ if ((top < 0) || (bottom < 0) || (left < 0) || (right < 0)) { | |||
+ top = Fl::screen_num(x(), y(), w(), h()); | |||
+ bottom = top; | |||
+ left = top; | |||
+ right = top; | |||
+ } | |||
+ | |||
+ send_wm_event(fl_xid(this), fl_NET_WM_FULLSCREEN_MONITORS, | |||
+ top, bottom, left, right); | |||
send_wm_state_event(fl_xid(this), 1, fl_NET_WM_STATE_FULLSCREEN); | |||
} else { | |||
_set_fullscreen(); | |||
@@ -1997,7 +2023,7 @@ void Fl_X::make_xid(Fl_Window* win, XVis | |||
// force the window to be on-screen. Usually the X window manager | |||
// does this, but a few don't, so we do it here for consistency: | |||
int scr_x, scr_y, scr_w, scr_h; | |||
- Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h, X, Y); | |||
+ Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h, X, Y, W, H); | |||
if (win->border()) { | |||
// ensure border is on screen: | |||
@@ -2026,6 +2052,23 @@ void Fl_X::make_xid(Fl_Window* win, XVis | |||
return; | |||
} | |||
+ // Compute which screen(s) we should be on if we want to go fullscreen | |||
+ int fullscreen_top, fullscreen_bottom, fullscreen_left, fullscreen_right; | |||
+ | |||
+ fullscreen_top = win->fullscreen_screen_top; | |||
+ fullscreen_bottom = win->fullscreen_screen_bottom; | |||
+ fullscreen_left = win->fullscreen_screen_left; | |||
+ fullscreen_right = win->fullscreen_screen_right; | |||
+ | |||
+ if ((fullscreen_top < 0) || (fullscreen_bottom < 0) || | |||
+ (fullscreen_left < 0) || (fullscreen_right < 0)) { | |||
+ fullscreen_top = Fl::screen_num(X, Y, W, H); | |||
+ fullscreen_bottom = fullscreen_top; | |||
+ fullscreen_left = fullscreen_top; | |||
+ fullscreen_right = fullscreen_top; | |||
+ } | |||
+ | |||
+ | |||
ulong root = win->parent() ? | |||
fl_xid(win->window()) : RootWindow(fl_display, fl_screen); | |||
@@ -2049,9 +2092,17 @@ void Fl_X::make_xid(Fl_Window* win, XVis | |||
// border, and cannot grab without an existing window. Besides, | |||
// there is no clear_override(). | |||
if (win->flags() & Fl_Widget::FULLSCREEN && !Fl_X::ewmh_supported()) { | |||
+ int sx, sy, sw, sh; | |||
attr.override_redirect = 1; | |||
mask |= CWOverrideRedirect; | |||
- Fl::screen_xywh(X, Y, W, H, X, Y, W, H); | |||
+ Fl::screen_xywh(sx, sy, sw, sh, fullscreen_left); | |||
+ X = sx; | |||
+ Fl::screen_xywh(sx, sy, sw, sh, fullscreen_right); | |||
+ W = sx + sw - X; | |||
+ Fl::screen_xywh(sx, sy, sw, sh, fullscreen_top); | |||
+ Y = sy; | |||
+ Fl::screen_xywh(sx, sy, sw, sh, fullscreen_bottom); | |||
+ H = sy + sh - Y; | |||
} | |||
if (fl_background_pixel >= 0) { | |||
@@ -2122,6 +2173,13 @@ void Fl_X::make_xid(Fl_Window* win, XVis | |||
// If asked for, create fullscreen | |||
if (win->flags() & Fl_Widget::FULLSCREEN && Fl_X::ewmh_supported()) { | |||
+ unsigned long data[4]; | |||
+ data[0] = fullscreen_top; | |||
+ data[1] = fullscreen_bottom; | |||
+ data[2] = fullscreen_left; | |||
+ data[3] = fullscreen_right; | |||
+ XChangeProperty (fl_display, xp->xid, fl_NET_WM_FULLSCREEN_MONITORS, XA_ATOM, 32, | |||
+ PropModeReplace, (unsigned char*) data, 4); | |||
XChangeProperty (fl_display, xp->xid, fl_NET_WM_STATE, XA_ATOM, 32, | |||
PropModeAppend, (unsigned char*) &fl_NET_WM_STATE_FULLSCREEN, 1); | |||
} | |||
diff -urp fltk-1.3.2.org/test/fullscreen.cxx fltk-1.3.2/test/fullscreen.cxx | |||
--- fltk-1.3.2.org/test/fullscreen.cxx 2012-06-14 17:09:46.000000000 +0200 | |||
+++ fltk-1.3.2/test/fullscreen.cxx 2013-01-16 10:52:47.881104801 +0100 | |||
@@ -127,7 +127,7 @@ class fullscreen_window : public Fl_Sing | |||
fullscreen_window(int W, int H, const char *t=0); | |||
int handle (int e); | |||
Fl_Toggle_Light_Button *b3; | |||
- | |||
+ Fl_Toggle_Light_Button *b4; | |||
}; | |||
fullscreen_window::fullscreen_window(int W, int H, const char *t) : Fl_Single_Window(W, H, t) { | |||
@@ -170,23 +170,54 @@ void border_cb(Fl_Widget *o, void *p) { | |||
#endif | |||
} | |||
-int px,py,pw,ph; | |||
Fl_Button *border_button; | |||
void fullscreen_cb(Fl_Widget *o, void *p) { | |||
Fl_Window *w = (Fl_Window *)p; | |||
int d = ((Fl_Button *)o)->value(); | |||
if (d) { | |||
- px = w->x(); | |||
- py = w->y(); | |||
- pw = w->w(); | |||
- ph = w->h(); | |||
+ if (((fullscreen_window*)w)->b4->value()) { | |||
+ int top, bottom, left, right; | |||
+ int top_y, bottom_y, left_x, right_x; | |||
+ | |||
+ int sx, sy, sw, sh; | |||
+ | |||
+ top = bottom = left = right = 0; | |||
+ | |||
+ Fl::screen_xywh(sx, sy, sw, sh, 0); | |||
+ top_y = sy; | |||
+ bottom_y = sy + sh; | |||
+ left_x = sx; | |||
+ right_x = sx + sw; | |||
+ | |||
+ for (int i = 1;i < Fl::screen_count();i++) { | |||
+ Fl::screen_xywh(sx, sy, sw, sh, i); | |||
+ if (sy < top_y) { | |||
+ top = i; | |||
+ top_y = sy; | |||
+ } | |||
+ if ((sy + sh) > bottom_y) { | |||
+ bottom = i; | |||
+ bottom_y = sy + sh; | |||
+ } | |||
+ if (sx < left_x) { | |||
+ left = i; | |||
+ left_x = sx; | |||
+ } | |||
+ if ((sx + sw) > right_x) { | |||
+ right = i; | |||
+ right_x = sx + sw; | |||
+ } | |||
+ } | |||
+ | |||
+ w->fullscreen_screens(top, bottom, left, right); | |||
+ } else { | |||
+ w->fullscreen_screens(-1, -1, -1, -1); | |||
+ } | |||
w->fullscreen(); | |||
- w->override(); | |||
#ifndef WIN32 // update our border state in case border was turned off | |||
border_button->value(w->border()); | |||
#endif | |||
} else { | |||
- //w->fullscreen_off(px,py,pw,ph); | |||
w->fullscreen_off(); | |||
} | |||
} | |||
@@ -219,7 +250,7 @@ void exit_cb(Fl_Widget *, void *) { | |||
exit(0); | |||
} | |||
-#define NUMB 7 | |||
+#define NUMB 8 | |||
int twowindow = 0; | |||
int initfull = 0; | |||
@@ -284,6 +315,9 @@ int main(int argc, char **argv) { | |||
window.b3->callback(fullscreen_cb,w); | |||
y+=30; | |||
+ window.b4 = new Fl_Toggle_Light_Button(50,y,window.w()-60,30,"All Screens"); | |||
+ y+=30; | |||
+ | |||
Fl_Button eb(50,y,window.w()-60,30,"Exit"); | |||
eb.callback(exit_cb); | |||
y+=30; |
@@ -0,0 +1,256 @@ | |||
diff -ur fltk-1.3.0r9293.org/src/Fl_win32.cxx fltk-1.3.0r9293/src/Fl_win32.cxx | |||
--- fltk-1.3.0r9293.org/src/Fl_win32.cxx 2012-06-18 09:07:56.522314557 +0200 | |||
+++ fltk-1.3.0r9293/src/Fl_win32.cxx 2012-06-18 09:08:07.392836285 +0200 | |||
@@ -87,6 +87,8 @@ | |||
static Fl_Display_Device fl_gdi_display(&fl_gdi_driver); | |||
Fl_Display_Device *Fl_Display_Device::_display = &fl_gdi_display; // the platform display | |||
+bool use_simple_keyboard = false; | |||
+ | |||
// dynamic wsock dll handling api: | |||
#if defined(__CYGWIN__) && !defined(SOCKET) | |||
# define SOCKET int | |||
@@ -120,6 +122,8 @@ | |||
* size and link dependencies. | |||
*/ | |||
static HMODULE s_imm_module = 0; | |||
+typedef BOOL (WINAPI* flTypeImmAssociateContextEx)(HWND, HIMC, DWORD); | |||
+static flTypeImmAssociateContextEx flImmAssociateContextEx = 0; | |||
typedef HIMC (WINAPI* flTypeImmGetContext)(HWND); | |||
static flTypeImmGetContext flImmGetContext = 0; | |||
typedef BOOL (WINAPI* flTypeImmSetCompositionWindow)(HIMC, LPCOMPOSITIONFORM); | |||
@@ -135,6 +139,7 @@ | |||
if (!s_imm_module) | |||
Fl::fatal("FLTK Lib Error: IMM32.DLL file not found!\n\n" | |||
"Please check your input method manager library accessibility."); | |||
+ flImmAssociateContextEx = (flTypeImmAssociateContextEx)GetProcAddress(s_imm_module, "ImmAssociateContextEx"); | |||
flImmGetContext = (flTypeImmGetContext)GetProcAddress(s_imm_module, "ImmGetContext"); | |||
flImmSetCompositionWindow = (flTypeImmSetCompositionWindow)GetProcAddress(s_imm_module, "ImmSetCompositionWindow"); | |||
flImmReleaseContext = (flTypeImmReleaseContext)GetProcAddress(s_imm_module, "ImmReleaseContext"); | |||
@@ -413,7 +418,12 @@ | |||
} | |||
} | |||
- TranslateMessage(&fl_msg); | |||
+ // Don't bother with key to character translation as we do | |||
+ // it manually for simpley keyboard widgets. In fact, calling | |||
+ // TranslateMessage() just makes it more difficult as it sets | |||
+ // a bunch of internal state. | |||
+ if (!use_simple_keyboard) | |||
+ TranslateMessage(&fl_msg); | |||
DispatchMessageW(&fl_msg); | |||
have_message = PeekMessageW(&fl_msg, NULL, 0, 0, PM_REMOVE); | |||
} | |||
@@ -638,6 +648,49 @@ | |||
} | |||
} | |||
+void fl_update_focus(void) | |||
+{ | |||
+ Fl_Widget *focus; | |||
+ Fl_Window *win; | |||
+ | |||
+ get_imm_module(); | |||
+ | |||
+ focus = Fl::grab(); | |||
+ if (!focus) | |||
+ focus = Fl::focus(); | |||
+ if (!focus) | |||
+ return; | |||
+ | |||
+ // Grabs are special in that events are sent to the first | |||
+ // available window | |||
+ if (focus == Fl::grab()) | |||
+ win = Fl::first_window(); | |||
+ else { | |||
+ win = focus->as_window(); | |||
+ if (!win) | |||
+ win = focus->window(); | |||
+ } | |||
+ | |||
+ if (!win) { | |||
+ Fl::warning("Cannot find window for widget receiving focus"); | |||
+ return; | |||
+ } | |||
+ | |||
+ // No Win32 window created yet | |||
+ if (!Fl_X::i(win) || !fl_xid(win)) | |||
+ return; | |||
+ | |||
+ if (focus->simple_keyboard()) { | |||
+ use_simple_keyboard = true; | |||
+ if (flImmGetContext(fl_xid(win)) != 0) | |||
+ flImmAssociateContextEx(fl_xid(win), 0, 0); | |||
+ } else { | |||
+ use_simple_keyboard = false; | |||
+ if (flImmGetContext(fl_xid(win)) == 0) | |||
+ flImmAssociateContextEx(fl_xid(win), 0, IACE_DEFAULT); | |||
+ } | |||
+} | |||
+ | |||
HWND fl_capture; | |||
static int mouse_event(Fl_Window *window, int what, int button, | |||
@@ -785,6 +838,27 @@ | |||
return extended ? extendedlut[vk] : vklut[vk]; | |||
} | |||
+static xchar msdead2fltk(xchar in) | |||
+{ | |||
+ switch (in) { | |||
+ case 0x0060: // GRAVE ACCENT | |||
+ return 0x0300; // COMBINING GRAVE ACCENT | |||
+ case 0x00b4: // ACUTE ACCENT | |||
+ return 0x0301; // COMBINING ACUTE ACCENT | |||
+ case 0x005e: // CIRCUMFLEX ACCENT | |||
+ return 0x0302; // COMBINING CIRCUMFLEX ACCENT | |||
+ case 0x007e: // TILDE | |||
+ return 0x0303; // COMBINING TILDE | |||
+ case 0x00a8: // DIAERESIS | |||
+ return 0x0308; // COMBINING DIAERESIS | |||
+ // FIXME: Windows dead key behaviour isn't documented and I don't have | |||
+ // any more keyboards to test with... | |||
+ } | |||
+ | |||
+ // hope that Windows gave us something proper to begin with | |||
+ return in; | |||
+} | |||
+ | |||
#if USE_COLORMAP | |||
extern HPALETTE fl_select_palette(void); // in fl_color_win32.cxx | |||
#endif | |||
@@ -846,6 +920,8 @@ | |||
//fl_msg.pt = ??? | |||
//fl_msg.lPrivate = ??? | |||
+ MSG fl_orig_msg = fl_msg; | |||
+ | |||
Fl_Window *window = fl_find(hWnd); | |||
if (window) switch (uMsg) { | |||
@@ -1025,23 +1101,82 @@ | |||
if (GetKeyState(VK_SCROLL)) state |= FL_SCROLL_LOCK; | |||
Fl::e_state = state; | |||
static char buffer[1024]; | |||
- if (uMsg == WM_CHAR || uMsg == WM_SYSCHAR) { | |||
+ if (use_simple_keyboard) { | |||
+ BYTE keystate[256]; | |||
+ WCHAR wbuf[8]; | |||
+ int ret; | |||
+ | |||
+ // I'm not sure if we ever get WM_CHAR (& friends) without an initial | |||
+ // WM_KEYDOWN (& friends), but if we do then we should not send such | |||
+ // side band events to simple keyboard widgets. | |||
+ if ((fl_orig_msg.message != WM_KEYDOWN) && | |||
+ (fl_orig_msg.message != WM_SYSKEYDOWN) && | |||
+ (fl_orig_msg.message != WM_KEYUP) && | |||
+ (fl_orig_msg.message != WM_SYSKEYUP)) | |||
+ break; | |||
+ | |||
+ GetKeyboardState(keystate); | |||
+ | |||
+ // Pressing Ctrl wreaks havoc with the symbol lookup, so turn that off. | |||
+ // But AltGr shows up as Ctrl+Alt in Windows, so keep Ctrl if Alt is | |||
+ // active. | |||
+ if (!(keystate[VK_MENU] & 0x80)) | |||
+ keystate[VK_CONTROL] = keystate[VK_LCONTROL] = keystate[VK_RCONTROL] = 0; | |||
+ | |||
+ // We cannot inspect or modify Windows' internal state of the keyboard | |||
+ // so we have to try to infer information from ToUnicode() and wedge | |||
+ // things into a known state. | |||
+ for (int i = 0;i < 2;i++) { | |||
+ ret = ToUnicode(fl_orig_msg.wParam, 0, keystate, wbuf, | |||
+ sizeof(wbuf)/sizeof(wbuf[0]), 0); | |||
+ | |||
+ // No symbol for this key (or unexpected length) | |||
+ if ((ret == 0) || (ret < -1)) { | |||
+ buffer[0] = 0; | |||
+ Fl::e_length = 0; | |||
+ break; | |||
+ } | |||
+ | |||
+ // A dead key. Convert this to a Unicode combining character so | |||
+ // that the application can tell the difference between dead and | |||
+ // normal keys. | |||
+ if (ret == -1) { | |||
+ xchar u = (xchar) msdead2fltk(wbuf[0]); | |||
+ Fl::e_length = fl_utf8fromwc(buffer, 1024, &u, 1); | |||
+ buffer[Fl::e_length] = 0; | |||
+ break; | |||
+ } | |||
+ | |||
+ // If we have two characters (or more) from ToUnicode(), that's | |||
+ // an invalid sequence. One character chould mean a proper symbol, | |||
+ // or it could mean a composed one. In both cases we need to call | |||
+ // ToUnicode() again to get something sane. | |||
+ if (i == 0) | |||
+ continue; | |||
+ | |||
+ // We should now have something sane. Give whatever we have to the | |||
+ // application. | |||
+ Fl::e_length = fl_utf8fromwc(buffer, 1024, wbuf, ret); | |||
+ buffer[Fl::e_length] = 0; | |||
+ } | |||
+ } else if (uMsg == WM_CHAR || uMsg == WM_SYSCHAR) { | |||
xchar u = (xchar) wParam; | |||
// Fl::e_length = fl_unicode2utf(&u, 1, buffer); | |||
Fl::e_length = fl_utf8fromwc(buffer, 1024, &u, 1); | |||
buffer[Fl::e_length] = 0; | |||
+ } else { | |||
+ buffer[0] = 0; | |||
+ Fl::e_length = 0; | |||
+ } | |||
- | |||
- } else if (Fl::e_keysym >= FL_KP && Fl::e_keysym <= FL_KP_Last) { | |||
- if (state & FL_NUM_LOCK) { | |||
- // Convert to regular keypress... | |||
- buffer[0] = Fl::e_keysym-FL_KP; | |||
- Fl::e_length = 1; | |||
- } else { | |||
- // Convert to special keypress... | |||
- buffer[0] = 0; | |||
- Fl::e_length = 0; | |||
+ // The keypad area is a bit odd in that we need to change the keysym | |||
+ // to properly indicate what the user meant, unlike other keys where | |||
+ // we normally change the text and keep keysym stable. | |||
+ if (Fl::e_keysym >= FL_KP && Fl::e_keysym <= FL_KP_Last) { | |||
+ // The initial mapping tables give us a keysym that corresponds to | |||
+ // numlock being on, so we only do something when it is off. | |||
+ if (!(state & FL_NUM_LOCK)) { | |||
switch (Fl::e_keysym) { | |||
case FL_KP + '0' : | |||
Fl::e_keysym = FL_Insert; | |||
@@ -1073,30 +1208,10 @@ | |||
case FL_KP + '.' : | |||
Fl::e_keysym = FL_Delete; | |||
break; | |||
- case FL_KP + '/' : | |||
- case FL_KP + '*' : | |||
- case FL_KP + '-' : | |||
- case FL_KP + '+' : | |||
- buffer[0] = Fl::e_keysym-FL_KP; | |||
- Fl::e_length = 1; | |||
- break; | |||
} | |||
} | |||
- } else if ((lParam & (1<<31))==0) { | |||
-#ifdef FLTK_PREVIEW_DEAD_KEYS | |||
- if ((lParam & (1<<24))==0) { // clear if dead key (always?) | |||
- xchar u = (xchar) wParam; | |||
- Fl::e_length = fl_utf8fromwc(buffer, 1024, &u, 1); | |||
- buffer[Fl::e_length] = 0; | |||
- } else { // set if "extended key" (never printable?) | |||
- buffer[0] = 0; | |||
- Fl::e_length = 0; | |||
- } | |||
-#else | |||
- buffer[0] = 0; | |||
- Fl::e_length = 0; | |||
-#endif | |||
} | |||
+ | |||
Fl::e_text = buffer; | |||
if (lParam & (1<<31)) { // key up events. | |||
if (Fl::handle(FL_KEYUP, window)) return 0; |
@@ -0,0 +1,286 @@ | |||
diff -ur fltk-1.3.0r9619.org/FL/Fl_Widget.H fltk-1.3.0r9619/FL/Fl_Widget.H | |||
--- fltk-1.3.0r9619.org/FL/Fl_Widget.H 2012-04-23 22:12:06.000000000 +0200 | |||
+++ fltk-1.3.0r9619/FL/Fl_Widget.H 2012-06-18 13:46:07.302320825 +0200 | |||
@@ -171,6 +171,7 @@ | |||
GROUP_RELATIVE = 1<<16, ///< position this widget relative to the parent group, not to the window | |||
COPIED_TOOLTIP = 1<<17, ///< the widget tooltip is internally copied, its destruction is handled by the widget | |||
FULLSCREEN = 1<<18, ///< a fullscreen window (Fl_Window) | |||
+ SIMPLE_KEYBOARD = 1<<19, ///< the widget wants simple, consistent keypresses and not advanced input (like character composition and CJK input) | |||
// (space for more flags) | |||
USERFLAG3 = 1<<29, ///< reserved for 3rd party extensions | |||
USERFLAG2 = 1<<30, ///< reserved for 3rd party extensions | |||
@@ -776,6 +777,35 @@ | |||
*/ | |||
void clear_changed() {flags_ &= ~CHANGED;} | |||
+ /** | |||
+ Returns if the widget sees a simplified keyboard model or not. | |||
+ | |||
+ Normally widgets get a full-featured keyboard model that is geared | |||
+ towards text input. This includes support for compose sequences and | |||
+ advanced input methods, commonly used for asian writing system. This | |||
+ system however has downsides in that extra graphic can be presented | |||
+ to the user and that a physical key press doesn't correspond directly | |||
+ to a FLTK event. | |||
+ | |||
+ Widgets that need a direct correspondence between actual key events | |||
+ and those seen by the widget can swith to the simplified keyboard | |||
+ model. | |||
+ | |||
+ \retval 0 if the widget uses the normal keyboard model | |||
+ \see set_changed(), clear_changed() | |||
+ */ | |||
+ unsigned int simple_keyboard() const {return flags_&SIMPLE_KEYBOARD;} | |||
+ | |||
+ /** Marks a widget to use the simple keyboard model. | |||
+ \see changed(), clear_changed() | |||
+ */ | |||
+ void set_simple_keyboard() {flags_ |= SIMPLE_KEYBOARD;} | |||
+ | |||
+ /** Marks a widget to use the normal keyboard model. | |||
+ \see changed(), set_changed() | |||
+ */ | |||
+ void set_normal_keyboard() {flags_ &= ~SIMPLE_KEYBOARD;} | |||
+ | |||
/** Gives the widget the keyboard focus. | |||
Tries to make this widget be the Fl::focus() widget, by first sending | |||
it an FL_FOCUS event, and if it returns non-zero, setting | |||
diff -ur fltk-1.3.0r9619.org/src/Fl.cxx fltk-1.3.0r9619/src/Fl.cxx | |||
--- fltk-1.3.0r9619.org/src/Fl.cxx 2012-03-23 17:47:53.000000000 +0100 | |||
+++ fltk-1.3.0r9619/src/Fl.cxx 2012-06-18 13:46:07.303320877 +0200 | |||
@@ -70,6 +70,8 @@ | |||
extern double fl_mac_flush_and_wait(double time_to_wait, char in_idle); | |||
#endif // WIN32 | |||
+extern void fl_update_focus(void); | |||
+ | |||
// | |||
// Globals... | |||
// | |||
@@ -876,6 +878,8 @@ | |||
fl_oldfocus = p; | |||
} | |||
e_number = old_event; | |||
+ // let the platform code do what it needs | |||
+ fl_update_focus(); | |||
} | |||
} | |||
diff -ur fltk-1.3.0r9619.org/src/Fl_grab.cxx fltk-1.3.0r9619/src/Fl_grab.cxx | |||
--- fltk-1.3.0r9619.org/src/Fl_grab.cxx 2012-03-23 17:47:53.000000000 +0100 | |||
+++ fltk-1.3.0r9619/src/Fl_grab.cxx 2012-06-18 13:46:07.303320877 +0200 | |||
@@ -29,6 +29,7 @@ | |||
// override_redirect, it does similar things on WIN32. | |||
extern void fl_fix_focus(); // in Fl.cxx | |||
+void fl_update_focus(void); | |||
#ifdef WIN32 | |||
// We have to keep track of whether we have captured the mouse, since | |||
@@ -80,6 +81,7 @@ | |||
#endif | |||
} | |||
grab_ = win; | |||
+ fl_update_focus(); | |||
} else { | |||
if (grab_) { | |||
#ifdef WIN32 | |||
@@ -98,6 +100,7 @@ | |||
XFlush(fl_display); | |||
#endif | |||
grab_ = 0; | |||
+ fl_update_focus(); | |||
fl_fix_focus(); | |||
} | |||
} | |||
diff -ur fltk-1.3.0r9619.org/src/Fl_x.cxx fltk-1.3.0r9619/src/Fl_x.cxx | |||
--- fltk-1.3.0r9619.org/src/Fl_x.cxx 2012-06-18 13:46:07.205316173 +0200 | |||
+++ fltk-1.3.0r9619/src/Fl_x.cxx 2012-06-18 13:46:18.216844629 +0200 | |||
@@ -298,6 +298,7 @@ | |||
Colormap fl_colormap; | |||
XIM fl_xim_im = 0; | |||
XIC fl_xim_ic = 0; | |||
+Window fl_xim_win = 0; | |||
char fl_is_over_the_spot = 0; | |||
static XRectangle status_area; | |||
@@ -583,6 +584,65 @@ | |||
if(xim_styles) XFree(xim_styles); | |||
} | |||
+void fl_xim_deactivate(void); | |||
+ | |||
+void fl_xim_activate(Window xid) | |||
+{ | |||
+ if (!fl_xim_im) | |||
+ return; | |||
+ | |||
+ // If the focused window has changed, then use the brute force method | |||
+ // of completely recreating the input context. | |||
+ if (fl_xim_win != xid) { | |||
+ fl_xim_deactivate(); | |||
+ | |||
+ fl_new_ic(); | |||
+ fl_xim_win = xid; | |||
+ | |||
+ XSetICValues(fl_xim_ic, | |||
+ XNFocusWindow, fl_xim_win, | |||
+ XNClientWindow, fl_xim_win, | |||
+ NULL); | |||
+ } | |||
+ | |||
+ fl_set_spot(spotf, spots, spot.x, spot.y, spot.width, spot.height); | |||
+} | |||
+ | |||
+void fl_xim_deactivate(void) | |||
+{ | |||
+ if (!fl_xim_ic) | |||
+ return; | |||
+ | |||
+ XDestroyIC(fl_xim_ic); | |||
+ fl_xim_ic = NULL; | |||
+ | |||
+ fl_xim_win = 0; | |||
+} | |||
+ | |||
+extern Fl_Window *fl_xfocus; | |||
+ | |||
+void fl_update_focus(void) | |||
+{ | |||
+ Fl_Widget *focus; | |||
+ | |||
+ focus = Fl::grab(); | |||
+ if (!focus) | |||
+ focus = Fl::focus(); | |||
+ if (!focus) | |||
+ return; | |||
+ | |||
+ if (focus->simple_keyboard()) { | |||
+ fl_xim_deactivate(); | |||
+ } else { | |||
+ // fl_xfocus should always be set if something has focus, but let's | |||
+ // play it safe | |||
+ if (!fl_xfocus || !fl_xid(fl_xfocus)) | |||
+ return; | |||
+ | |||
+ fl_xim_activate(fl_xid(fl_xfocus)); | |||
+ } | |||
+} | |||
+ | |||
void fl_open_display() { | |||
if (fl_display) return; | |||
@@ -917,10 +977,9 @@ | |||
XEvent xevent = thisevent; | |||
fl_xevent = &thisevent; | |||
Window xid = xevent.xany.window; | |||
- static Window xim_win = 0; | |||
if (fl_xim_ic && xevent.type == DestroyNotify && | |||
- xid != xim_win && !fl_find(xid)) | |||
+ xid != fl_xim_win && !fl_find(xid)) | |||
{ | |||
XIM xim_im; | |||
xim_im = XOpenIM(fl_display, NULL, NULL, NULL); | |||
@@ -935,48 +994,10 @@ | |||
return 0; | |||
} | |||
- if (fl_xim_ic && (xevent.type == FocusIn)) | |||
- { | |||
-#define POOR_XIM | |||
-#ifdef POOR_XIM | |||
- if (xim_win != xid) | |||
- { | |||
- xim_win = xid; | |||
- XDestroyIC(fl_xim_ic); | |||
- fl_xim_ic = NULL; | |||
- fl_new_ic(); | |||
- XSetICValues(fl_xim_ic, | |||
- XNFocusWindow, xevent.xclient.window, | |||
- XNClientWindow, xid, | |||
- NULL); | |||
- } | |||
- fl_set_spot(spotf, spots, spot.x, spot.y, spot.width, spot.height); | |||
-#else | |||
- if (Fl::first_window() && Fl::first_window()->modal()) { | |||
- Window x = fl_xid(Fl::first_window()); | |||
- if (x != xim_win) { | |||
- xim_win = x; | |||
- XSetICValues(fl_xim_ic, | |||
- XNFocusWindow, xim_win, | |||
- XNClientWindow, xim_win, | |||
- NULL); | |||
- fl_set_spot(spotf, spots, spot.x, spot.y, spot.width, spot.height); | |||
- } | |||
- } else if (xim_win != xid && xid) { | |||
- xim_win = xid; | |||
- XSetICValues(fl_xim_ic, | |||
- XNFocusWindow, xevent.xclient.window, | |||
- XNClientWindow, xid, | |||
- //XNFocusWindow, xim_win, | |||
- //XNClientWindow, xim_win, | |||
- NULL); | |||
- fl_set_spot(spotf, spots, spot.x, spot.y, spot.width, spot.height); | |||
- } | |||
-#endif | |||
+ if (fl_xim_ic) { | |||
+ if (XFilterEvent((XEvent *)&xevent, 0)) | |||
+ return 1; | |||
} | |||
- | |||
- if ( XFilterEvent((XEvent *)&xevent, 0) ) | |||
- return(1); | |||
#if USE_XRANDR | |||
if( XRRUpdateConfiguration_f && xevent.type == randrEventBase + RRScreenChangeNotify) { | |||
@@ -1326,15 +1347,15 @@ | |||
//static XComposeStatus compose; | |||
len = XLookupString((XKeyEvent*)&(xevent.xkey), | |||
buffer, buffer_len, &keysym, 0/*&compose*/); | |||
- if (keysym && keysym < 0x400) { // a character in latin-1,2,3,4 sets | |||
- // force it to type a character (not sure if this ever is needed): | |||
- // if (!len) {buffer[0] = char(keysym); len = 1;} | |||
- len = fl_utf8encode(XKeysymToUcs(keysym), buffer); | |||
- if (len < 1) len = 1; | |||
- // ignore all effects of shift on the keysyms, which makes it a lot | |||
- // easier to program shortcuts and is Windoze-compatible: | |||
- keysym = XKeycodeToKeysym(fl_display, keycode, 0); | |||
- } | |||
+ // XLookupString() is only defined to return Latin-1 (although it | |||
+ // often gives you more). To be safe, use our own lookups based on | |||
+ // keysym. | |||
+ len = fl_utf8encode(XKeysymToUcs(keysym), buffer); | |||
+ if (len < 1) | |||
+ len = 1; | |||
+ // ignore all effects of shift on the keysyms, which makes it a lot | |||
+ // easier to program shortcuts and is Windoze-compatable: | |||
+ keysym = XKeycodeToKeysym(fl_display, keycode, 0); | |||
} | |||
// MRS: Can't use Fl::event_state(FL_CTRL) since the state is not | |||
// set until set_event_xy() is called later... | |||
diff -ur fltk-1.3.0r9619.org/src/xutf8/imKStoUCS.c fltk-1.3.0r9619/src/xutf8/imKStoUCS.c | |||
--- fltk-1.3.0r9619.org/src/xutf8/imKStoUCS.c 2009-03-13 23:43:43.000000000 +0100 | |||
+++ fltk-1.3.0r9619/src/xutf8/imKStoUCS.c 2012-06-18 13:46:07.304320930 +0200 | |||
@@ -266,6 +266,12 @@ | |||
0x20a8, 0x20a9, 0x20aa, 0x20ab, 0x20ac /* 0x20a8-0x20af */ | |||
}; | |||
+static unsigned short const keysym_to_unicode_fe50_fe60[] = { | |||
+ 0x0300, 0x0301, 0x0302, 0x0303, 0x0304, 0x0306, 0x0307, 0x0308, /* 0xfe50-0xfe57 */ | |||
+ 0x030a, 0x030b, 0x030c, 0x0327, 0x0328, 0x1da5, 0x3099, 0x309a, /* 0xfe58-0xfe5f */ | |||
+ 0x0323 /* 0xfe60-0xfe67 */ | |||
+}; | |||
+ | |||
unsigned int | |||
KeySymToUcs4(KeySym keysym) | |||
{ | |||
@@ -315,6 +321,8 @@ | |||
return keysym_to_unicode_1e9f_1eff[keysym - 0x1e9f]; | |||
else if (keysym > 0x209f && keysym < 0x20ad) | |||
return keysym_to_unicode_20a0_20ac[keysym - 0x20a0]; | |||
+ else if (keysym > 0xfe4f && keysym < 0xfe61) | |||
+ return keysym_to_unicode_fe50_fe60[keysym - 0xfe50]; | |||
else | |||
return 0; | |||
} |
@@ -0,0 +1,350 @@ | |||
diff -up fltk-1.3.2/CMakeLists.txt.clp-x11 fltk-1.3.2/CMakeLists.txt | |||
--- fltk-1.3.2/CMakeLists.txt.clp-x11 2012-09-13 16:19:01.000000000 +0200 | |||
+++ fltk-1.3.2/CMakeLists.txt 2013-01-30 15:56:25.810663430 +0100 | |||
@@ -515,6 +515,20 @@ else() | |||
endif(OPTION_USE_XINERAMA) | |||
####################################################################### | |||
+if(X11_Xfixes_FOUND) | |||
+ option(OPTION_USE_XFIXES "use lib XFIXES" ON) | |||
+endif(X11_Xfixes_FOUND) | |||
+ | |||
+if(OPTION_USE_XFIXES) | |||
+ set(HAVE_XFIXES ${X11_Xfixes_FOUND}) | |||
+ include_directories(${X11_Xfixes_INCLUDE_PATH}) | |||
+ list(APPEND FLTK_LDLIBS -lXfixes) | |||
+ set(FLTK_XFIXES_FOUND TRUE) | |||
+else() | |||
+ set(FLTK_XFIXES_FOUND FALSE) | |||
+endif(OPTION_USE_XFIXES) | |||
+ | |||
+####################################################################### | |||
if(X11_Xft_FOUND) | |||
option(OPTION_USE_XFT "use lib Xft" ON) | |||
endif(X11_Xft_FOUND) | |||
diff -up fltk-1.3.2/configh.cmake.in.clp-x11 fltk-1.3.2/configh.cmake.in | |||
--- fltk-1.3.2/configh.cmake.in.clp-x11 2011-07-19 06:49:30.000000000 +0200 | |||
+++ fltk-1.3.2/configh.cmake.in 2013-01-30 15:56:25.810663430 +0100 | |||
@@ -108,6 +108,14 @@ | |||
#define USE_XDBE HAVE_XDBE | |||
/* | |||
+ * HAVE_XFIXES: | |||
+ * | |||
+ * Do we have the X fixes extension? | |||
+ */ | |||
+ | |||
+#cmakedefine01 HAVE_XFIXES | |||
+ | |||
+/* | |||
* __APPLE_QUARTZ__: | |||
* | |||
* If __APPLE_QUARTZ__ is defined, FLTK will be | |||
diff -up fltk-1.3.2/configh.in.clp-x11 fltk-1.3.2/configh.in | |||
--- fltk-1.3.2/configh.in.clp-x11 2011-10-04 11:21:47.000000000 +0200 | |||
+++ fltk-1.3.2/configh.in 2013-01-30 15:56:25.810663430 +0100 | |||
@@ -108,6 +108,14 @@ | |||
#define USE_XDBE HAVE_XDBE | |||
/* | |||
+ * HAVE_XFIXES: | |||
+ * | |||
+ * Do we have the X fixes extension? | |||
+ */ | |||
+ | |||
+#define HAVE_XFIXES 0 | |||
+ | |||
+/* | |||
* __APPLE_QUARTZ__: | |||
* | |||
* All Apple implementations are now based on Quartz and Cocoa, | |||
diff -up fltk-1.3.2/configure.in.clp-x11 fltk-1.3.2/configure.in | |||
--- fltk-1.3.2/configure.in.clp-x11 2013-01-30 15:56:25.802663573 +0100 | |||
+++ fltk-1.3.2/configure.in 2013-01-30 15:56:25.810663430 +0100 | |||
@@ -999,6 +999,16 @@ case $uname_GUI in | |||
LIBS="-lXext $LIBS") | |||
fi | |||
+ dnl Check for the Xfixes extension unless disabled... | |||
+ AC_ARG_ENABLE(xfixes, [ --enable-xfixes turn on Xfixes support [default=yes]]) | |||
+ | |||
+ if test x$enable_xfixes != xno; then | |||
+ AC_CHECK_HEADER(X11/extensions/Xfixes.h, AC_DEFINE(HAVE_XFIXES),, | |||
+ [#include <X11/Xlib.h>]) | |||
+ AC_CHECK_LIB(Xfixes, XFixesQueryExtension, | |||
+ LIBS="-lXfixes $LIBS") | |||
+ fi | |||
+ | |||
dnl Check for overlay visuals... | |||
AC_PATH_PROG(XPROP, xprop) | |||
AC_CACHE_CHECK(for X overlay visuals, ac_cv_have_overlay, | |||
diff -up fltk-1.3.2/fluid/CMakeLists.txt.clp-x11 fltk-1.3.2/fluid/CMakeLists.txt | |||
diff -up fltk-1.3.2/src/CMakeLists.txt.clp-x11 fltk-1.3.2/src/CMakeLists.txt | |||
--- fltk-1.3.2/src/CMakeLists.txt.clp-x11 2013-01-30 16:06:00.785430590 +0100 | |||
+++ fltk-1.3.2/src/CMakeLists.txt 2013-01-30 16:06:17.883126642 +0100 | |||
@@ -243,6 +243,10 @@ if(HAVE_XINERAMA) | |||
target_link_libraries(fltk ${X11_Xinerama_LIB}) | |||
endif(HAVE_XINERAMA) | |||
+if(HAVE_XFIXES) | |||
+ target_link_libraries(fltk ${X11_Xfixes_LIB}) | |||
+endif(HAVE_XFIXES) | |||
+ | |||
if(USE_XFT) | |||
target_link_libraries(fltk ${X11_Xft_LIB}) | |||
endif(USE_XFT) | |||
diff -up fltk-1.3.2/src/Fl_x.cxx.clp-x11 fltk-1.3.2/src/Fl_x.cxx | |||
--- fltk-1.3.2/src/Fl_x.cxx.clp-x11 2013-01-30 15:56:25.793663733 +0100 | |||
+++ fltk-1.3.2/src/Fl_x.cxx 2013-01-30 16:03:37.355981103 +0100 | |||
@@ -53,6 +53,12 @@ static XRRUpdateConfiguration_type XRRUp | |||
static int randrEventBase; // base of RandR-defined events | |||
#endif | |||
+# if HAVE_XFIXES | |||
+# include <X11/extensions/Xfixes.h> | |||
+static int xfixes_event_base = 0; | |||
+static bool have_xfixes = false; | |||
+# endif | |||
+ | |||
static Fl_Xlib_Graphics_Driver fl_xlib_driver; | |||
static Fl_Display_Device fl_xlib_display(&fl_xlib_driver); | |||
Fl_Display_Device *Fl_Display_Device::_display = &fl_xlib_display;// the platform display | |||
@@ -307,6 +313,9 @@ static Atom WM_PROTOCOLS; | |||
static Atom fl_MOTIF_WM_HINTS; | |||
static Atom TARGETS; | |||
static Atom CLIPBOARD; | |||
+static Atom TIMESTAMP; | |||
+static Atom PRIMARY_TIMESTAMP; | |||
+static Atom CLIPBOARD_TIMESTAMP; | |||
Atom fl_XdndAware; | |||
Atom fl_XdndSelection; | |||
Atom fl_XdndEnter; | |||
@@ -667,6 +676,9 @@ void fl_open_display(Display* d) { | |||
fl_MOTIF_WM_HINTS = XInternAtom(d, "_MOTIF_WM_HINTS", 0); | |||
TARGETS = XInternAtom(d, "TARGETS", 0); | |||
CLIPBOARD = XInternAtom(d, "CLIPBOARD", 0); | |||
+ TIMESTAMP = XInternAtom(d, "TIMESTAMP", 0); | |||
+ PRIMARY_TIMESTAMP = XInternAtom(d, "PRIMARY_TIMESTAMP", 0); | |||
+ CLIPBOARD_TIMESTAMP = XInternAtom(d, "CLIPBOARD_TIMESTAMP", 0); | |||
fl_XdndAware = XInternAtom(d, "XdndAware", 0); | |||
fl_XdndSelection = XInternAtom(d, "XdndSelection", 0); | |||
fl_XdndEnter = XInternAtom(d, "XdndEnter", 0); | |||
@@ -713,6 +725,15 @@ void fl_open_display(Display* d) { | |||
#if !USE_COLORMAP | |||
Fl::visual(FL_RGB); | |||
#endif | |||
+ | |||
+#if HAVE_XFIXES | |||
+ int error_base; | |||
+ if (XFixesQueryExtension(fl_display, &xfixes_event_base, &error_base)) | |||
+ have_xfixes = true; | |||
+ else | |||
+ have_xfixes = false; | |||
+#endif | |||
+ | |||
#if USE_XRANDR | |||
void *libxrandr_addr = dlopen("libXrandr.so.2", RTLD_LAZY); | |||
if (!libxrandr_addr) libxrandr_addr = dlopen("libXrandr.so", RTLD_LAZY); | |||
@@ -901,6 +922,102 @@ void Fl::copy(const char *stuff, int len | |||
} | |||
//////////////////////////////////////////////////////////////// | |||
+// Code for tracking clipboard changes: | |||
+ | |||
+static Time primary_timestamp = -1; | |||
+static Time clipboard_timestamp = -1; | |||
+ | |||
+extern bool fl_clipboard_notify_empty(void); | |||
+extern void fl_trigger_clipboard_notify(int source); | |||
+ | |||
+static void poll_clipboard_owner(void) { | |||
+ Window xid; | |||
+ | |||
+#if HAVE_XFIXES | |||
+ // No polling needed with Xfixes | |||
+ if (have_xfixes) | |||
+ return; | |||
+#endif | |||
+ | |||
+ // No one is interested, so no point polling | |||
+ if (fl_clipboard_notify_empty()) | |||
+ return; | |||
+ | |||
+ // We need a window for this to work | |||
+ if (!Fl::first_window()) | |||
+ return; | |||
+ xid = fl_xid(Fl::first_window()); | |||
+ if (!xid) | |||
+ return; | |||
+ | |||
+ // Request an update of the selection time for both the primary and | |||
+ // clipboard selections. Magic continues when we get a SelectionNotify. | |||
+ if (!fl_i_own_selection[0]) | |||
+ XConvertSelection(fl_display, XA_PRIMARY, TIMESTAMP, PRIMARY_TIMESTAMP, | |||
+ xid, fl_event_time); | |||
+ if (!fl_i_own_selection[1]) | |||
+ XConvertSelection(fl_display, CLIPBOARD, TIMESTAMP, CLIPBOARD_TIMESTAMP, | |||
+ xid, fl_event_time); | |||
+} | |||
+ | |||
+static void clipboard_timeout(void *data) | |||
+{ | |||
+ // No one is interested, so stop polling | |||
+ if (fl_clipboard_notify_empty()) | |||
+ return; | |||
+ | |||
+ poll_clipboard_owner(); | |||
+ | |||
+ Fl::repeat_timeout(0.5, clipboard_timeout); | |||
+} | |||
+ | |||
+static void handle_clipboard_timestamp(int clipboard, Time time) | |||
+{ | |||
+ Time *timestamp; | |||
+ | |||
+ timestamp = clipboard ? &clipboard_timestamp : &primary_timestamp; | |||
+ | |||
+#if HAVE_XFIXES | |||
+ if (!have_xfixes) | |||
+#endif | |||
+ { | |||
+ // Initial scan, just store the value | |||
+ if (*timestamp == (Time)-1) { | |||
+ *timestamp = time; | |||
+ return; | |||
+ } | |||
+ } | |||
+ | |||
+ // Same selection | |||
+ if (time == *timestamp) | |||
+ return; | |||
+ | |||
+ *timestamp = time; | |||
+ | |||
+ // Something happened! Let's tell someone! | |||
+ fl_trigger_clipboard_notify(clipboard); | |||
+} | |||
+ | |||
+void fl_clipboard_notify_change() { | |||
+ // Reset the timestamps if we've going idle so that you don't | |||
+ // get a bogus immediate trigger next time they're activated. | |||
+ if (fl_clipboard_notify_empty()) { | |||
+ primary_timestamp = -1; | |||
+ clipboard_timestamp = -1; | |||
+ } else { | |||
+#if HAVE_XFIXES | |||
+ if (!have_xfixes) | |||
+#endif | |||
+ { | |||
+ poll_clipboard_owner(); | |||
+ | |||
+ if (!Fl::has_timeout(clipboard_timeout)) | |||
+ Fl::add_timeout(0.5, clipboard_timeout); | |||
+ } | |||
+ } | |||
+} | |||
+ | |||
+//////////////////////////////////////////////////////////////// | |||
const XEvent* fl_xevent; // the current x event | |||
ulong fl_event_time; // the last timestamp from an x event | |||
@@ -1024,7 +1141,6 @@ int fl_handle(const XEvent& thisevent) | |||
return 0; | |||
case SelectionNotify: { | |||
- if (!fl_selection_requestor) return 0; | |||
static unsigned char* buffer = 0; | |||
if (buffer) {XFree(buffer); buffer = 0;} | |||
long bytesread = 0; | |||
@@ -1040,6 +1156,19 @@ int fl_handle(const XEvent& thisevent) | |||
bytesread/4, 65536, 1, 0, | |||
&actual, &format, &count, &remaining, | |||
&portion)) break; // quit on error | |||
+ | |||
+ if ((fl_xevent->xselection.property == PRIMARY_TIMESTAMP) || | |||
+ (fl_xevent->xselection.property == CLIPBOARD_TIMESTAMP)) { | |||
+ if (portion && format == 32 && count == 1) { | |||
+ Time t = *(unsigned int*)portion; | |||
+ if (fl_xevent->xselection.property == CLIPBOARD_TIMESTAMP) | |||
+ handle_clipboard_timestamp(1, t); | |||
+ else | |||
+ handle_clipboard_timestamp(0, t); | |||
+ } | |||
+ return true; | |||
+ } | |||
+ | |||
if (actual == TARGETS || actual == XA_ATOM) { | |||
Atom type = XA_STRING; | |||
for (unsigned i = 0; i<count; i++) { | |||
@@ -1076,6 +1205,9 @@ int fl_handle(const XEvent& thisevent) | |||
buffer[bytesread] = 0; | |||
convert_crlf(buffer, bytesread); | |||
} | |||
+ | |||
+ if (!fl_selection_requestor) return 0; | |||
+ | |||
Fl::e_text = buffer ? (char*)buffer : (char *)""; | |||
Fl::e_length = bytesread; | |||
int old_event = Fl::e_number; | |||
@@ -1096,6 +1228,7 @@ int fl_handle(const XEvent& thisevent) | |||
case SelectionClear: { | |||
int clipboard = fl_xevent->xselectionclear.selection == CLIPBOARD; | |||
fl_i_own_selection[clipboard] = 0; | |||
+ poll_clipboard_owner(); | |||
return 1;} | |||
case SelectionRequest: { | |||
@@ -1308,6 +1441,9 @@ int fl_handle(const XEvent& thisevent) | |||
case FocusIn: | |||
if (fl_xim_ic) XSetICFocus(fl_xim_ic); | |||
event = FL_FOCUS; | |||
+ // If the user has toggled from another application to this one, | |||
+ // then it's a good time to check for clipboard changes. | |||
+ poll_clipboard_owner(); | |||
break; | |||
case FocusOut: | |||
@@ -1676,6 +1812,25 @@ int fl_handle(const XEvent& thisevent) | |||
} | |||
} | |||
+#if HAVE_XFIXES | |||
+ switch (xevent.type - xfixes_event_base) { | |||
+ case XFixesSelectionNotify: { | |||
+ // Someone feeding us bogus events? | |||
+ if (!have_xfixes) | |||
+ return true; | |||
+ | |||
+ XFixesSelectionNotifyEvent *selection_notify = (XFixesSelectionNotifyEvent *)&xevent; | |||
+ | |||
+ if ((selection_notify->selection == XA_PRIMARY) && !fl_i_own_selection[0]) | |||
+ handle_clipboard_timestamp(0, selection_notify->selection_timestamp); | |||
+ else if ((selection_notify->selection == CLIPBOARD) && !fl_i_own_selection[1]) | |||
+ handle_clipboard_timestamp(1, selection_notify->selection_timestamp); | |||
+ | |||
+ return true; | |||
+ } | |||
+ } | |||
+#endif | |||
+ | |||
return Fl::handle(event, window); | |||
} | |||
@@ -1995,6 +2150,16 @@ void Fl_X::make_xid(Fl_Window* win, XVis | |||
XChangeProperty(fl_display, xp->xid, net_wm_type, XA_ATOM, 32, PropModeReplace, (unsigned char*)&net_wm_type_kind, 1); | |||
} | |||
+#if HAVE_XFIXES | |||
+ // register for clipboard change notifications | |||
+ if (have_xfixes && !win->parent()) { | |||
+ XFixesSelectSelectionInput(fl_display, xp->xid, XA_PRIMARY, | |||
+ XFixesSetSelectionOwnerNotifyMask); | |||
+ XFixesSelectSelectionInput(fl_display, xp->xid, CLIPBOARD, | |||
+ XFixesSetSelectionOwnerNotifyMask); | |||
+ } | |||
+#endif | |||
+ | |||
XMapWindow(fl_display, xp->xid); | |||
if (showit) { | |||
win->set_visible(); | |||
diff -up fltk-1.3.2/test/CMakeLists.txt.clp-x11 fltk-1.3.2/test/CMakeLists.txt |
@@ -0,0 +1,355 @@ | |||
diff -up fltk-1.3.2/CMakeLists.txt.clp-x11 fltk-1.3.2/CMakeLists.txt | |||
--- fltk-1.3.2/CMakeLists.txt.clp-x11 2012-09-13 16:19:01.000000000 +0200 | |||
+++ fltk-1.3.2/CMakeLists.txt 2013-01-30 15:56:25.810663430 +0100 | |||
@@ -515,6 +515,20 @@ else() | |||
endif(OPTION_USE_XINERAMA) | |||
####################################################################### | |||
+if(X11_Xfixes_FOUND) | |||
+ option(OPTION_USE_XFIXES "use lib XFIXES" ON) | |||
+endif(X11_Xfixes_FOUND) | |||
+ | |||
+if(OPTION_USE_XFIXES) | |||
+ set(HAVE_XFIXES ${X11_Xfixes_FOUND}) | |||
+ include_directories(${X11_Xfixes_INCLUDE_PATH}) | |||
+ list(APPEND FLTK_LDLIBS -lXfixes) | |||
+ set(FLTK_XFIXES_FOUND TRUE) | |||
+else() | |||
+ set(FLTK_XFIXES_FOUND FALSE) | |||
+endif(OPTION_USE_XFIXES) | |||
+ | |||
+####################################################################### | |||
if(X11_Xft_FOUND) | |||
option(OPTION_USE_XFT "use lib Xft" ON) | |||
endif(X11_Xft_FOUND) | |||
diff -up fltk-1.3.2/configh.cmake.in.clp-x11 fltk-1.3.2/configh.cmake.in | |||
--- fltk-1.3.2/configh.cmake.in.clp-x11 2011-07-19 06:49:30.000000000 +0200 | |||
+++ fltk-1.3.2/configh.cmake.in 2013-01-30 15:56:25.810663430 +0100 | |||
@@ -108,6 +108,14 @@ | |||
#define USE_XDBE HAVE_XDBE | |||
/* | |||
+ * HAVE_XFIXES: | |||
+ * | |||
+ * Do we have the X fixes extension? | |||
+ */ | |||
+ | |||
+#cmakedefine01 HAVE_XFIXES | |||
+ | |||
+/* | |||
* __APPLE_QUARTZ__: | |||
* | |||
* If __APPLE_QUARTZ__ is defined, FLTK will be | |||
diff -up fltk-1.3.2/configh.in.clp-x11 fltk-1.3.2/configh.in | |||
--- fltk-1.3.2/configh.in.clp-x11 2011-10-04 11:21:47.000000000 +0200 | |||
+++ fltk-1.3.2/configh.in 2013-01-30 15:56:25.810663430 +0100 | |||
@@ -108,6 +108,14 @@ | |||
#define USE_XDBE HAVE_XDBE | |||
/* | |||
+ * HAVE_XFIXES: | |||
+ * | |||
+ * Do we have the X fixes extension? | |||
+ */ | |||
+ | |||
+#define HAVE_XFIXES 0 | |||
+ | |||
+/* | |||
* __APPLE_QUARTZ__: | |||
* | |||
* All Apple implementations are now based on Quartz and Cocoa, | |||
diff -up fltk-1.3.2/configure.in.clp-x11 fltk-1.3.2/configure.in | |||
--- fltk-1.3.2/configure.in.clp-x11 2013-01-30 15:56:25.802663573 +0100 | |||
+++ fltk-1.3.2/configure.in 2013-01-30 15:56:25.810663430 +0100 | |||
@@ -999,6 +999,16 @@ case $uname_GUI in | |||
LIBS="-lXext $LIBS") | |||
fi | |||
+ dnl Check for the Xfixes extension unless disabled... | |||
+ AC_ARG_ENABLE(xfixes, [ --enable-xfixes turn on Xfixes support [default=yes]]) | |||
+ | |||
+ if test x$enable_xfixes != xno; then | |||
+ AC_CHECK_HEADER(X11/extensions/Xfixes.h, AC_DEFINE(HAVE_XFIXES),, | |||
+ [#include <X11/Xlib.h>]) | |||
+ AC_CHECK_LIB(Xfixes, XFixesQueryExtension, | |||
+ LIBS="-lXfixes $LIBS") | |||
+ fi | |||
+ | |||
dnl Check for overlay visuals... | |||
AC_PATH_PROG(XPROP, xprop) | |||
AC_CACHE_CHECK(for X overlay visuals, ac_cv_have_overlay, | |||
diff -up fltk-1.3.2/fluid/CMakeLists.txt.clp-x11 fltk-1.3.2/fluid/CMakeLists.txt | |||
diff -up fltk-1.3.2/src/CMakeLists.txt.clp-x11 fltk-1.3.2/src/CMakeLists.txt | |||
--- fltk-1.3.2/src/CMakeLists.txt.clp-x11 2013-01-30 16:06:00.785430590 +0100 | |||
+++ fltk-1.3.2/src/CMakeLists.txt 2013-01-30 16:06:17.883126642 +0100 | |||
@@ -243,6 +243,10 @@ if(HAVE_XINERAMA) | |||
target_link_libraries(fltk ${X11_Xinerama_LIB}) | |||
endif(HAVE_XINERAMA) | |||
+if(HAVE_XFIXES) | |||
+ target_link_libraries(fltk ${X11_Xfixes_LIB}) | |||
+endif(HAVE_XFIXES) | |||
+ | |||
if(USE_XFT) | |||
target_link_libraries(fltk ${X11_Xft_LIB}) | |||
endif(USE_XFT) | |||
diff -up fltk-1.3.2/src/Fl_x.cxx.clp-x11 fltk-1.3.2/src/Fl_x.cxx | |||
--- fltk-1.3.2/src/Fl_x.cxx.clp-x11 2013-01-30 15:56:25.793663733 +0100 | |||
+++ fltk-1.3.2/src/Fl_x.cxx 2013-01-30 16:03:37.355981103 +0100 | |||
@@ -53,6 +53,12 @@ static XRRUpdateConfiguration_type XRRUp | |||
static int randrEventBase; // base of RandR-defined events | |||
#endif | |||
+# if HAVE_XFIXES | |||
+# include <X11/extensions/Xfixes.h> | |||
+static int xfixes_event_base = 0; | |||
+static bool have_xfixes = false; | |||
+# endif | |||
+ | |||
static Fl_Xlib_Graphics_Driver fl_xlib_driver; | |||
static Fl_Display_Device fl_xlib_display(&fl_xlib_driver); | |||
Fl_Display_Device *Fl_Display_Device::_display = &fl_xlib_display;// the platform display | |||
@@ -307,6 +313,9 @@ static Atom WM_PROTOCOLS; | |||
static Atom fl_MOTIF_WM_HINTS; | |||
static Atom TARGETS; | |||
static Atom CLIPBOARD; | |||
+static Atom TIMESTAMP; | |||
+static Atom PRIMARY_TIMESTAMP; | |||
+static Atom CLIPBOARD_TIMESTAMP; | |||
Atom fl_XdndAware; | |||
Atom fl_XdndSelection; | |||
Atom fl_XdndEnter; | |||
@@ -667,6 +676,9 @@ void fl_open_display(Display* d) { | |||
fl_MOTIF_WM_HINTS = XInternAtom(d, "_MOTIF_WM_HINTS", 0); | |||
TARGETS = XInternAtom(d, "TARGETS", 0); | |||
CLIPBOARD = XInternAtom(d, "CLIPBOARD", 0); | |||
+ TIMESTAMP = XInternAtom(d, "TIMESTAMP", 0); | |||
+ PRIMARY_TIMESTAMP = XInternAtom(d, "PRIMARY_TIMESTAMP", 0); | |||
+ CLIPBOARD_TIMESTAMP = XInternAtom(d, "CLIPBOARD_TIMESTAMP", 0); | |||
fl_XdndAware = XInternAtom(d, "XdndAware", 0); | |||
fl_XdndSelection = XInternAtom(d, "XdndSelection", 0); | |||
fl_XdndEnter = XInternAtom(d, "XdndEnter", 0); | |||
@@ -713,6 +725,15 @@ void fl_open_display(Display* d) { | |||
#if !USE_COLORMAP | |||
Fl::visual(FL_RGB); | |||
#endif | |||
+ | |||
+#if HAVE_XFIXES | |||
+ int error_base; | |||
+ if (XFixesQueryExtension(fl_display, &xfixes_event_base, &error_base)) | |||
+ have_xfixes = true; | |||
+ else | |||
+ have_xfixes = false; | |||
+#endif | |||
+ | |||
#if USE_XRANDR | |||
void *libxrandr_addr = dlopen("libXrandr.so.2", RTLD_LAZY); | |||
if (!libxrandr_addr) libxrandr_addr = dlopen("libXrandr.so", RTLD_LAZY); | |||
@@ -901,6 +922,107 @@ void Fl::copy(const char *stuff, int len | |||
} | |||
//////////////////////////////////////////////////////////////// | |||
+// Code for tracking clipboard changes: | |||
+ | |||
+static Time primary_timestamp = -1; | |||
+static Time clipboard_timestamp = -1; | |||
+ | |||
+extern bool fl_clipboard_notify_empty(void); | |||
+extern void fl_trigger_clipboard_notify(int source); | |||
+ | |||
+static void poll_clipboard_owner(void) { | |||
+ Window xid; | |||
+ | |||
+#if HAVE_XFIXES | |||
+ // No polling needed with Xfixes | |||
+ if (have_xfixes) | |||
+ return; | |||
+#endif | |||
+ | |||
+ // No one is interested, so no point polling | |||
+ if (fl_clipboard_notify_empty()) | |||
+ return; | |||
+ | |||
+ // We need a window for this to work | |||
+ if (!Fl::first_window()) | |||
+ return; | |||
+ xid = fl_xid(Fl::first_window()); | |||
+ if (!xid) | |||
+ return; | |||
+ | |||
+ // Request an update of the selection time for both the primary and | |||
+ // clipboard selections. Magic continues when we get a SelectionNotify. | |||
+ if (!fl_i_own_selection[0]) | |||
+ XConvertSelection(fl_display, XA_PRIMARY, TIMESTAMP, PRIMARY_TIMESTAMP, | |||
+ xid, fl_event_time); | |||
+ if (!fl_i_own_selection[1]) | |||
+ XConvertSelection(fl_display, CLIPBOARD, TIMESTAMP, CLIPBOARD_TIMESTAMP, | |||
+ xid, fl_event_time); | |||
+} | |||
+ | |||
+static void clipboard_timeout(void *data) | |||
+{ | |||
+ // No one is interested, so stop polling | |||
+ if (fl_clipboard_notify_empty()) | |||
+ return; | |||
+ | |||
+ poll_clipboard_owner(); | |||
+ | |||
+ Fl::repeat_timeout(0.5, clipboard_timeout); | |||
+} | |||
+ | |||
+static void handle_clipboard_timestamp(int clipboard, Time time) | |||
+{ | |||
+ Time *timestamp; | |||
+ | |||
+ timestamp = clipboard ? &clipboard_timestamp : &primary_timestamp; | |||
+ | |||
+#if HAVE_XFIXES | |||
+ if (!have_xfixes) | |||
+#endif | |||
+ { | |||
+ // Initial scan, just store the value | |||
+ if (*timestamp == (Time)-1) { | |||
+ *timestamp = time; | |||
+ return; | |||
+ } | |||
+ } | |||
+ | |||
+ // Same selection | |||
+ if (time == *timestamp) | |||
+ return; | |||
+ | |||
+ *timestamp = time; | |||
+ | |||
+ // The clipboard change is the event that caused us to request | |||
+ // the clipboard data, so use that time as the latest event. | |||
+ if (time > fl_event_time) | |||
+ fl_event_time = time; | |||
+ | |||
+ // Something happened! Let's tell someone! | |||
+ fl_trigger_clipboard_notify(clipboard); | |||
+} | |||
+ | |||
+void fl_clipboard_notify_change() { | |||
+ // Reset the timestamps if we've going idle so that you don't | |||
+ // get a bogus immediate trigger next time they're activated. | |||
+ if (fl_clipboard_notify_empty()) { | |||
+ primary_timestamp = -1; | |||
+ clipboard_timestamp = -1; | |||
+ } else { | |||
+#if HAVE_XFIXES | |||
+ if (!have_xfixes) | |||
+#endif | |||
+ { | |||
+ poll_clipboard_owner(); | |||
+ | |||
+ if (!Fl::has_timeout(clipboard_timeout)) | |||
+ Fl::add_timeout(0.5, clipboard_timeout); | |||
+ } | |||
+ } | |||
+} | |||
+ | |||
+//////////////////////////////////////////////////////////////// | |||
const XEvent* fl_xevent; // the current x event | |||
ulong fl_event_time; // the last timestamp from an x event | |||
@@ -1024,7 +1141,6 @@ int fl_handle(const XEvent& thisevent) | |||
return 0; | |||
case SelectionNotify: { | |||
- if (!fl_selection_requestor) return 0; | |||
static unsigned char* buffer = 0; | |||
if (buffer) {XFree(buffer); buffer = 0;} | |||
long bytesread = 0; | |||
@@ -1040,6 +1156,19 @@ int fl_handle(const XEvent& thisevent) | |||
bytesread/4, 65536, 1, 0, | |||
&actual, &format, &count, &remaining, | |||
&portion)) break; // quit on error | |||
+ | |||
+ if ((fl_xevent->xselection.property == PRIMARY_TIMESTAMP) || | |||
+ (fl_xevent->xselection.property == CLIPBOARD_TIMESTAMP)) { | |||
+ if (portion && format == 32 && count == 1) { | |||
+ Time t = *(unsigned int*)portion; | |||
+ if (fl_xevent->xselection.property == CLIPBOARD_TIMESTAMP) | |||
+ handle_clipboard_timestamp(1, t); | |||
+ else | |||
+ handle_clipboard_timestamp(0, t); | |||
+ } | |||
+ return true; | |||
+ } | |||
+ | |||
if (actual == TARGETS || actual == XA_ATOM) { | |||
Atom type = XA_STRING; | |||
for (unsigned i = 0; i<count; i++) { | |||
@@ -1076,6 +1205,9 @@ int fl_handle(const XEvent& thisevent) | |||
buffer[bytesread] = 0; | |||
convert_crlf(buffer, bytesread); | |||
} | |||
+ | |||
+ if (!fl_selection_requestor) return 0; | |||
+ | |||
Fl::e_text = buffer ? (char*)buffer : (char *)""; | |||
Fl::e_length = bytesread; | |||
int old_event = Fl::e_number; | |||
@@ -1096,6 +1228,7 @@ int fl_handle(const XEvent& thisevent) | |||
case SelectionClear: { | |||
int clipboard = fl_xevent->xselectionclear.selection == CLIPBOARD; | |||
fl_i_own_selection[clipboard] = 0; | |||
+ poll_clipboard_owner(); | |||
return 1;} | |||
case SelectionRequest: { | |||
@@ -1308,6 +1441,9 @@ int fl_handle(const XEvent& thisevent) | |||
case FocusIn: | |||
if (fl_xim_ic) XSetICFocus(fl_xim_ic); | |||
event = FL_FOCUS; | |||
+ // If the user has toggled from another application to this one, | |||
+ // then it's a good time to check for clipboard changes. | |||
+ poll_clipboard_owner(); | |||
break; | |||
case FocusOut: | |||
@@ -1676,6 +1812,25 @@ int fl_handle(const XEvent& thisevent) | |||
} | |||
} | |||
+#if HAVE_XFIXES | |||
+ switch (xevent.type - xfixes_event_base) { | |||
+ case XFixesSelectionNotify: { | |||
+ // Someone feeding us bogus events? | |||
+ if (!have_xfixes) | |||
+ return true; | |||
+ | |||
+ XFixesSelectionNotifyEvent *selection_notify = (XFixesSelectionNotifyEvent *)&xevent; | |||
+ | |||
+ if ((selection_notify->selection == XA_PRIMARY) && !fl_i_own_selection[0]) | |||
+ handle_clipboard_timestamp(0, selection_notify->selection_timestamp); | |||
+ else if ((selection_notify->selection == CLIPBOARD) && !fl_i_own_selection[1]) | |||
+ handle_clipboard_timestamp(1, selection_notify->selection_timestamp); | |||
+ | |||
+ return true; | |||
+ } | |||
+ } | |||
+#endif | |||
+ | |||
return Fl::handle(event, window); | |||
} | |||
@@ -1995,6 +2150,16 @@ void Fl_X::make_xid(Fl_Window* win, XVis | |||
XChangeProperty(fl_display, xp->xid, net_wm_type, XA_ATOM, 32, PropModeReplace, (unsigned char*)&net_wm_type_kind, 1); | |||
} | |||
+#if HAVE_XFIXES | |||
+ // register for clipboard change notifications | |||
+ if (have_xfixes && !win->parent()) { | |||
+ XFixesSelectSelectionInput(fl_display, xp->xid, XA_PRIMARY, | |||
+ XFixesSetSelectionOwnerNotifyMask); | |||
+ XFixesSelectSelectionInput(fl_display, xp->xid, CLIPBOARD, | |||
+ XFixesSetSelectionOwnerNotifyMask); | |||
+ } | |||
+#endif | |||
+ | |||
XMapWindow(fl_display, xp->xid); | |||
if (showit) { | |||
win->set_visible(); | |||
diff -up fltk-1.3.2/test/CMakeLists.txt.clp-x11 fltk-1.3.2/test/CMakeLists.txt |
@@ -0,0 +1,375 @@ | |||
diff -ur fltk-1.3.0r9619.org/configure.in fltk-1.3.0r9619/configure.in | |||
--- fltk-1.3.0r9619.org/configure.in 2012-04-22 04:45:09.000000000 +0200 | |||
+++ fltk-1.3.0r9619/configure.in 2012-06-18 13:47:33.290447462 +0200 | |||
@@ -865,6 +865,8 @@ | |||
Darwin*) | |||
# MacOS X uses Cocoa for graphics. | |||
LIBS="$LIBS -framework Cocoa" | |||
+ # And some Carbon for keyboard handling | |||
+ LIBS="$LIBS -framework Carbon" | |||
if test x$have_pthread = xyes; then | |||
AC_DEFINE(HAVE_PTHREAD) | |||
diff -ur fltk-1.3.0r9619.org/src/Fl_cocoa.mm fltk-1.3.0r9619/src/Fl_cocoa.mm | |||
--- fltk-1.3.0r9619.org/src/Fl_cocoa.mm 2012-06-16 10:49:52.000000000 +0200 | |||
+++ fltk-1.3.0r9619/src/Fl_cocoa.mm 2012-06-18 13:47:42.944910782 +0200 | |||
@@ -53,6 +53,7 @@ | |||
#include <math.h> | |||
#import <Cocoa/Cocoa.h> | |||
+#import <Carbon/Carbon.h> | |||
#ifndef NSINTEGER_DEFINED // appears with 10.5 in NSObjCRuntime.h | |||
#if defined(__LP64__) && __LP64__ | |||
@@ -114,6 +115,8 @@ | |||
extern Fl_Window* fl_xmousewin; | |||
#endif | |||
+bool use_simple_keyboard = false; | |||
+ | |||
enum { FLTKTimerEvent = 1, FLTKDataReadyEvent }; | |||
@@ -130,6 +133,39 @@ | |||
{ | |||
} | |||
+// Undocumented voodoo. Taken from Mozilla. | |||
+#define ENABLE_ROMAN_KYBDS_ONLY -23 | |||
+ | |||
+void fl_update_focus(void) | |||
+{ | |||
+ Fl_Widget *focus; | |||
+ | |||
+ focus = Fl::grab(); | |||
+ if (!focus) | |||
+ focus = Fl::focus(); | |||
+ if (!focus) | |||
+ return; | |||
+ | |||
+ if (focus->simple_keyboard()) | |||
+ use_simple_keyboard = true; | |||
+ else | |||
+ use_simple_keyboard = false; | |||
+ | |||
+ // Force a "Roman" or "ASCII" keyboard, which both the Mozilla and | |||
+ // Safari people seem to think implies turning off advanced IME stuff | |||
+ // (see nsTSMManager::SyncKeyScript in Mozilla and enableSecureTextInput | |||
+ // in Safari/Webcore). Should be good enough for us then... | |||
+#if (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5) | |||
+ CFArrayRef inputSources = TISCreateASCIICapableInputSourceList(); | |||
+ TSMSetDocumentProperty(TSMGetActiveDocument(), | |||
+ kTSMDocumentEnabledInputSourcesPropertyTag, | |||
+ sizeof(CFArrayRef), &inputSources); | |||
+ CFRelease(inputSources); | |||
+#else | |||
+ KeyScript(use_simple_keyboard ? ENABLE_ROMAN_KYBDS_ONLY : smKeyEnableKybds); | |||
+#endif | |||
+} | |||
+ | |||
/* | |||
* Mac keyboard lookup table | |||
*/ | |||
@@ -908,6 +944,25 @@ | |||
} | |||
@end | |||
+static const char* cocoaDead2FLTK(const char *in) | |||
+{ | |||
+ if (strcmp(in, "\140") == 0) // GRAVE ACCENT | |||
+ return "\314\200"; // COMBINING GRAVE ACCENT | |||
+ if (strcmp(in, "\302\264") == 0) // ACUTE ACCENT | |||
+ return "\314\201"; // COMBINING ACUTE ACCENT | |||
+ if (strcmp(in, "\136") == 0) // CIRCUMFLEX ACCENT | |||
+ return "\314\202"; // COMBINING CIRCUMFLEX ACCENT | |||
+ if (strcmp(in, "\176") == 0) // TILDE | |||
+ return "\314\203"; // COMBINING TILDE | |||
+ if (strcmp(in, "\302\250") == 0) // DIAERESIS | |||
+ return "\314\210"; // COMBINING DIAERESIS | |||
+ // FIXME: OS X dead key behaviour isn't documented and I don't have | |||
+ // any more keyboards to test with... | |||
+ | |||
+ // hope that OS X gave us something proper to begin with | |||
+ return in; | |||
+} | |||
+ | |||
/* | |||
Handle cocoa keyboard events | |||
Events during a character composition sequence: | |||
@@ -1648,6 +1703,7 @@ | |||
- (void)rightMouseDragged:(NSEvent *)theEvent; | |||
- (void)otherMouseDragged:(NSEvent *)theEvent; | |||
- (void)scrollWheel:(NSEvent *)theEvent; | |||
- (BOOL)handleKeyDown:(NSEvent *)theEvent; | |||
- (void)keyDown:(NSEvent *)theEvent; | |||
- (void)keyUp:(NSEvent *)theEvent; | |||
@@ -1726,6 +1782,130 @@ | |||
- (void)scrollWheel:(NSEvent *)theEvent { | |||
cocoaMouseWheelHandler(theEvent); | |||
} | |||
+ const UCKeyboardLayout *layout; | |||
+ OSStatus err; | |||
+ | |||
+ layout = NULL; | |||
+ | |||
+#if (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5) | |||
+ TISInputSourceRef keyboard; | |||
+ CFDataRef uchr; | |||
+ | |||
+ keyboard = TISCopyCurrentKeyboardInputSource(); | |||
+ uchr = (CFDataRef)TISGetInputSourceProperty(keyboard, | |||
+ kTISPropertyUnicodeKeyLayoutData); | |||
+ if (uchr == NULL) | |||
+ return nil; | |||
+ | |||
+ layout = (const UCKeyboardLayout*)CFDataGetBytePtr(uchr); | |||
+#else | |||
+ KeyboardLayoutRef old_layout; | |||
+ int kind; | |||
+ | |||
+ err = KLGetCurrentKeyboardLayout(&old_layout); | |||
+ if (err != noErr) | |||
+ return nil; | |||
+ | |||
+ err = KLGetKeyboardLayoutProperty(old_layout, kKLKind, | |||
+ (const void**)&kind); | |||
+ if (err != noErr) | |||
+ return nil; | |||
+ | |||
+ // Old, crufty layout format? | |||
+ if (kind == kKLKCHRKind) { | |||
+ void *kchr_layout; | |||
+ | |||
+ UInt32 chars, state; | |||
+ char buf[3]; | |||
+ | |||
+ unichar result[16]; | |||
+ ByteCount in_len, out_len; | |||
+ | |||
+ err = KLGetKeyboardLayoutProperty(old_layout, kKLKCHRData, | |||
+ (const void**)&kchr_layout); | |||
+ if (err != noErr) | |||
+ return nil; | |||
+ | |||
+ state = 0; | |||
+ | |||
+ keyCode &= 0x7f; | |||
+ modifierFlags &= 0xff00; | |||
+ | |||
+ chars = KeyTranslate(kchr_layout, keyCode | modifierFlags, &state); | |||
+ | |||
+ buf[0] = (chars >> 16) & 0xff; | |||
+ buf[1] = chars & 0xff; | |||
+ buf[2] = '\0'; | |||
+ | |||
+ if (buf[0] == '\0') { | |||
+ buf[0] = buf[1]; | |||
+ buf[1] = '\0'; | |||
+ } | |||
+ | |||
+ // The data is now in some layout specific encoding. Need to convert | |||
+ // this to unicode. | |||
+ | |||
+ ScriptCode script; | |||
+ TextEncoding encoding; | |||
+ TECObjectRef converter; | |||
+ | |||
+ script = (ScriptCode)GetScriptManagerVariable(smKeyScript); | |||
+ | |||
+ err = UpgradeScriptInfoToTextEncoding(script, kTextLanguageDontCare, | |||
+ kTextRegionDontCare, NULL, | |||
+ &encoding); | |||
+ if (err != noErr) | |||
+ return nil; | |||
+ | |||
+ err = TECCreateConverter(&converter, encoding, kTextEncodingUnicodeV4_0); | |||
+ if (err != noErr) | |||
+ return nil; | |||
+ | |||
+ in_len = strlen(buf); | |||
+ out_len = sizeof(result); | |||
+ | |||
+ err = TECConvertText(converter, (ConstTextPtr)buf, in_len, &in_len, | |||
+ (TextPtr)result, out_len, &out_len); | |||
+ | |||
+ TECDisposeConverter(converter); | |||
+ | |||
+ if (err != noErr) | |||
+ return nil; | |||
+ | |||
+ return [NSString stringWithCharacters:result | |||
+ length:(out_len / sizeof(unichar))]; | |||
+ } | |||
+ | |||
+ if ((kind != kKLKCHRuchrKind) && (kind != kKLuchrKind)) | |||
+ return nil; | |||
+ | |||
+ err = KLGetKeyboardLayoutProperty(old_layout, kKLuchrData, | |||
+ (const void**)&layout); | |||
+ if (err != noErr) | |||
+ return nil; | |||
+#endif | |||
+ | |||
+ if (layout == NULL) | |||
+ return nil; | |||
+ | |||
+ UInt32 dead_state; | |||
+ UniCharCount max_len, actual_len; | |||
+ UniChar string[255]; | |||
+ | |||
+ dead_state = 0; | |||
+ max_len = sizeof(string)/sizeof(*string); | |||
+ | |||
+ modifierFlags = (modifierFlags >> 8) & 0xff; | |||
+ | |||
+ err = UCKeyTranslate(layout, keyCode, kUCKeyActionDown, modifierFlags, | |||
+ LMGetKbdType(), 0, &dead_state, max_len, &actual_len, | |||
+ string); | |||
+ if (err != noErr) | |||
+ return nil; | |||
+ | |||
+ return [NSString stringWithCharacters:string length:actual_len]; | |||
+} | |||
- (BOOL)handleKeyDown:(NSEvent *)theEvent { | |||
//NSLog(@"handleKeyDown"); | |||
fl_lock_function(); | |||
@@ -1752,14 +1932,47 @@ | |||
break; | |||
} | |||
} | |||
- if (!no_text_key && !(Fl::e_state & FL_META) ) { | |||
- // Don't send cmd-<key> to interpretKeyEvents because it beeps. | |||
+ if (!no_text_key) { | |||
+ // The simple keyboard model will ignore insertText, so we need to grab | |||
+ // the symbol directly from the event. Note that we still use setMarkedText. | |||
+ if (use_simple_keyboard) { | |||
+ NSString *simple_chars; | |||
+ UInt32 modifiers; | |||
+ | |||
+ // We want a "normal" symbol out of the event, which basically means | |||
+ // we only respect the shift and alt/altgr modifiers. Cocoa can help | |||
+ // us if we only wanted shift, but as we also want alt/altgr, we'll | |||
+ // have to do some lookup ourselves. This matches our behaviour on | |||
+ // other platforms. | |||
+ | |||
+ modifiers = 0; | |||
+ if ([theEvent modifierFlags] & NSAlphaShiftKeyMask) | |||
+ modifiers |= alphaLock; | |||
+ if ([theEvent modifierFlags] & NSShiftKeyMask) | |||
+ modifiers |= shiftKey; | |||
+ if ([theEvent modifierFlags] & NSAlternateKeyMask) | |||
+ modifiers |= optionKey; | |||
+ | |||
+ simple_chars = [FLView keyTranslate:[theEvent keyCode] | |||
+ withModifierFlags:modifiers]; | |||
+ if (simple_chars == nil) { | |||
+ // Something went wrong. Fall back to what Cocoa gave us... | |||
+ simple_chars = [theEvent charactersIgnoringModifiers]; | |||
+ } | |||
+ | |||
+ [FLView prepareEtext:simple_chars]; | |||
+ } | |||
+ | |||
// Then we can let the OS have a stab at it and see if it thinks it | |||
// should result in some text | |||
- NSText *edit = [[theEvent window] fieldEditor:YES forObject:nil]; | |||
- in_key_event = true; | |||
- [edit interpretKeyEvents:[NSArray arrayWithObject:theEvent]]; | |||
- in_key_event = false; | |||
+ | |||
+ // Don't send cmd-<key> to interpretKeyEvents because it beeps. | |||
+ if (!(Fl::e_state & FL_META)) { | |||
+ NSText *edit = [[theEvent window] fieldEditor:YES forObject:nil]; | |||
+ in_key_event = true; | |||
+ [edit interpretKeyEvents:[NSArray arrayWithObject:theEvent]]; | |||
+ in_key_event = false; | |||
+ } | |||
} | |||
//NSLog(@"to text=%@ l=%d", [NSString stringWithUTF8String:Fl::e_text], Fl::e_length); | |||
int handled = Fl::handle(FL_KEYDOWN, window); | |||
@@ -1937,21 +2150,30 @@ | |||
//NSLog(@"insertText: received=%@",received); | |||
if (!in_key_event) fl_lock_function(); | |||
+ | |||
+ // Simple keyboard widgets do not want these side channel inputs. | |||
+ if (use_simple_keyboard) | |||
+ goto end; | |||
+ | |||
[FLView prepareEtext:received]; | |||
+ | |||
// We can get called outside of key events (e.g. from the character | |||
- // palette). Transform such actions to FL_PASTE events. | |||
+ // palette). We need to fake our own key event at that point. | |||
if (!in_key_event) { | |||
Fl_Window *target = [(FLWindow*)[self window] getFl_Window]; | |||
- Fl::handle(FL_PASTE, target); | |||
+ Fl::e_keysym = Fl::e_original_keysym = 0; | |||
+ Fl::handle(FL_KEYDOWN, target); | |||
// for some reason, the window does not redraw until the next mouse move or button push | |||
// sending a 'redraw()' or 'awake()' does not solve the issue! | |||
Fl::flush(); | |||
} | |||
+ | |||
+end: | |||
if (!in_key_event) fl_unlock_function(); | |||
} | |||
- (void)setMarkedText:(id)aString selectedRange:(NSRange)newSelection { | |||
- NSString *received; | |||
+ NSString *received, *current, *aggregate; | |||
if (newSelection.location == 0) { | |||
[self unmarkText]; | |||
return; | |||
@@ -1962,11 +2184,47 @@ | |||
received = (NSString*)aString; | |||
} | |||
//NSLog(@"setMarkedText: %@ %d %d",received,newSelection.location,newSelection.length); | |||
+ | |||
+ fl_lock_function(); | |||
+ | |||
+ // Simple keyboard widgets generally do not want these side channel | |||
+ // inputs, but we have no other way of getting dead keys so we make | |||
+ // an exception in that case. | |||
+ if (use_simple_keyboard) { | |||
+ if (in_key_event && (Fl::e_length == 0)) { | |||
+ [FLView prepareEtext:received]; | |||
+ | |||
+ Fl::e_text = (char*)cocoaDead2FLTK(Fl::e_text); | |||
+ Fl::e_length = strlen(Fl::e_text); | |||
+ } | |||
+ goto end; | |||
+ } | |||
+ | |||
// This code creates the OS X behaviour of seeing dead keys as things | |||
// are being composed. | |||
+ // | |||
+ // Note: The concatenation thing is because of how OS X deals with | |||
+ // invalid sequences. At that point it will spit out one call | |||
+ // to insertText with the now aborted sequence, and one new | |||
+ // call to setMarkedText with the new sequence. Since we want | |||
+ // both to be visible, we need to concatenate. | |||
next_compose_length = newSelection.location; | |||
- [FLView prepareEtext:received]; | |||
- //NSLog(@"Fl::e_text=%@ Fl::e_length=%d next_compose_length=%d", received, Fl::e_length, next_compose_length); | |||
+ current = [NSString stringWithUTF8String:Fl::e_text]; | |||
+ aggregate = [current stringByAppendingString:received]; | |||
+ | |||
+ [FLView prepareEtext:aggregate]; | |||
+ //NSLog(@"Fl::e_text=%@ Fl::e_length=%d next_compose_length=%d", aggregate, Fl::e_length, next_compose_length); | |||
+ | |||
+ // We can get called outside of key events (e.g. from the character | |||
+ // palette). We need to fake our own key event at that point. | |||
+ if (!in_key_event) { | |||
+ Fl_Window *target = [(FLWindow*)[self window] getFl_Window]; | |||
+ Fl::e_keysym = Fl::e_original_keysym = 0; | |||
+ Fl::handle(FL_KEYDOWN, target); | |||
+ } | |||
+ | |||
+end: | |||
+ fl_unlock_function(); | |||
} | |||
- (void)unmarkText { |
@@ -0,0 +1,11 @@ | |||
--- freetype-2.1.10/include/freetype/config/ftoption.h.enable-ft2-bci 2005-10-12 13:50:40.000000000 -0400 | |||
+++ freetype-2.1.10/include/freetype/config/ftoption.h 2005-10-12 14:18:50.000000000 -0400 | |||
@@ -436,7 +436,7 @@ | |||
/* Do not #undef this macro here, since the build system might */ | |||
/* define it for certain configurations only. */ | |||
/* */ | |||
-/* #define TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ | |||
+#define TT_CONFIG_OPTION_BYTECODE_INTERPRETER | |||
/*************************************************************************/ |
@@ -0,0 +1,20 @@ | |||
--- freetype-2.2.1/modules.cfg.orig 2006-07-07 21:01:09.000000000 -0400 | |||
+++ freetype-2.2.1/modules.cfg 2006-07-07 21:01:54.000000000 -0400 | |||
@@ -110,7 +110,7 @@ | |||
AUX_MODULES += cache | |||
# TrueType GX/AAT table validation. Needs ftgxval.c below. | |||
-# AUX_MODULES += gxvalid | |||
+AUX_MODULES += gxvalid | |||
# Support for streams compressed with gzip (files with suffix .gz). | |||
# | |||
@@ -124,7 +124,7 @@ | |||
# OpenType table validation. Needs ftotval.c below. | |||
# | |||
-# AUX_MODULES += otvalid | |||
+AUX_MODULES += otvalid | |||
# Auxiliary PostScript driver component to share common code. | |||
# |
@@ -0,0 +1,11 @@ | |||
--- freetype-2.3.0/include/freetype/config/ftoption.h.spf 2007-01-18 14:27:34.000000000 -0500 | |||
+++ freetype-2.3.0/include/freetype/config/ftoption.h 2007-01-18 14:27:48.000000000 -0500 | |||
@@ -92,7 +92,7 @@ | |||
/* This is done to allow FreeType clients to run unmodified, forcing */ | |||
/* them to display normal gray-level anti-aliased glyphs. */ | |||
/* */ | |||
-/* #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ | |||
+#define FT_CONFIG_OPTION_SUBPIXEL_RENDERING | |||
/*************************************************************************/ |
@@ -0,0 +1,101 @@ | |||
--- freetype-2.3.11/src/cff/cffgload.c.CVE-2010-1797-2 2009-09-10 17:52:21.000000000 +0200 | |||
+++ freetype-2.3.11/src/cff/cffgload.c 2010-08-11 13:39:32.000000000 +0200 | |||
@@ -2358,8 +2358,11 @@ | |||
return CFF_Err_Unimplemented_Feature; | |||
} | |||
- decoder->top = args; | |||
+ decoder->top = args; | |||
+ if ( decoder->top - stack >= CFF_MAX_OPERANDS ) | |||
+ goto Stack_Overflow; | |||
+ | |||
} /* general operator processing */ | |||
} /* while ip < limit */ | |||
@@ -2627,48 +2630,54 @@ | |||
/* now load the unscaled outline */ | |||
error = cff_get_glyph_data( face, glyph_index, | |||
&charstring, &charstring_len ); | |||
- if ( !error ) | |||
- { | |||
- error = cff_decoder_prepare( &decoder, size, glyph_index ); | |||
- if ( !error ) | |||
- { | |||
- error = cff_decoder_parse_charstrings( &decoder, | |||
- charstring, | |||
- charstring_len ); | |||
+ if ( error ) | |||
+ goto Glyph_Build_Finished; | |||
+ | |||
+ error = cff_decoder_prepare( &decoder, size, glyph_index ); | |||
+ if ( error ) | |||
+ goto Glyph_Build_Finished; | |||
- cff_free_glyph_data( face, &charstring, charstring_len ); | |||
+ error = cff_decoder_parse_charstrings( &decoder, | |||
+ charstring, | |||
+ charstring_len ); | |||
+ | |||
+ cff_free_glyph_data( face, &charstring, charstring_len ); | |||
+ | |||
+ if ( error ) | |||
+ goto Glyph_Build_Finished; | |||
#ifdef FT_CONFIG_OPTION_INCREMENTAL | |||
- /* Control data and length may not be available for incremental */ | |||
- /* fonts. */ | |||
- if ( face->root.internal->incremental_interface ) | |||
- { | |||
- glyph->root.control_data = 0; | |||
- glyph->root.control_len = 0; | |||
- } | |||
- else | |||
+ /* Control data and length may not be available for incremental */ | |||
+ /* fonts. */ | |||
+ if ( face->root.internal->incremental_interface ) | |||
+ { | |||
+ glyph->root.control_data = 0; | |||
+ glyph->root.control_len = 0; | |||
+ } | |||
+ else | |||
#endif /* FT_CONFIG_OPTION_INCREMENTAL */ | |||
- /* We set control_data and control_len if charstrings is loaded. */ | |||
- /* See how charstring loads at cff_index_access_element() in */ | |||
- /* cffload.c. */ | |||
- { | |||
- CFF_Index csindex = &cff->charstrings_index; | |||
+ /* We set control_data and control_len if charstrings is loaded. */ | |||
+ /* See how charstring loads at cff_index_access_element() in */ | |||
+ /* cffload.c. */ | |||
+ { | |||
+ CFF_Index csindex = &cff->charstrings_index; | |||
- if ( csindex->offsets ) | |||
- { | |||
- glyph->root.control_data = csindex->bytes + | |||
- csindex->offsets[glyph_index] - 1; | |||
- glyph->root.control_len = charstring_len; | |||
- } | |||
- } | |||
+ if ( csindex->offsets ) | |||
+ { | |||
+ glyph->root.control_data = csindex->bytes + | |||
+ csindex->offsets[glyph_index] - 1; | |||
+ glyph->root.control_len = charstring_len; | |||
} | |||
} | |||
- /* save new glyph tables */ | |||
- cff_builder_done( &decoder.builder ); | |||
+ Glyph_Build_Finished: | |||
+ /* save new glyph tables, if no error */ | |||
+ if ( !error ) | |||
+ cff_builder_done( &decoder.builder ); | |||
+ /* XXX: anything to do for broken glyph entry? */ | |||
} | |||
#ifdef FT_CONFIG_OPTION_INCREMENTAL |
@@ -0,0 +1,35 @@ | |||
--- freetype-2.3.11/src/pshinter/pshalgo.c 2009-07-03 15:28:24.000000000 +0200 | |||
+++ freetype-2.3.11/src/pshinter/pshalgo.c 2010-07-13 13:14:22.000000000 +0200 | |||
@@ -4,7 +4,8 @@ | |||
/* */ | |||
/* PostScript hinting algorithm (body). */ | |||
/* */ | |||
-/* Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ | |||
+/* Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 */ | |||
+/* by */ | |||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ | |||
/* */ | |||
/* This file is part of the FreeType project, and may only be used */ | |||
@@ -1690,7 +1691,10 @@ | |||
/* process secondary hints to `selected' points */ | |||
if ( num_masks > 1 && glyph->num_points > 0 ) | |||
{ | |||
- first = mask->end_point; | |||
+ /* the `endchar' op can reduce the number of points */ | |||
+ first = mask->end_point > glyph->num_points | |||
+ ? glyph->num_points | |||
+ : mask->end_point; | |||
mask++; | |||
for ( ; num_masks > 1; num_masks--, mask++ ) | |||
{ | |||
@@ -1698,7 +1702,9 @@ | |||
FT_Int count; | |||
- next = mask->end_point; | |||
+ next = mask->end_point > glyph->num_points | |||
+ ? glyph->num_points | |||
+ : mask->end_point; | |||
count = next - first; | |||
if ( count > 0 ) | |||
{ |
@@ -0,0 +1,39 @@ | |||
--- freetype-2.3.11/src/base/ftobjs.c 2009-09-02 08:42:41.000000000 +0200 | |||
+++ freetype-2.3.11/src/base/ftobjs.c 2010-07-12 16:39:13.000000000 +0200 | |||
@@ -1531,6 +1531,8 @@ | |||
len += rlen; | |||
else | |||
{ | |||
+ if ( pfb_lenpos + 3 > pfb_len + 2 ) | |||
+ goto Exit2; | |||
pfb_data[pfb_lenpos ] = (FT_Byte)( len ); | |||
pfb_data[pfb_lenpos + 1] = (FT_Byte)( len >> 8 ); | |||
pfb_data[pfb_lenpos + 2] = (FT_Byte)( len >> 16 ); | |||
@@ -1539,6 +1541,8 @@ | |||
if ( ( flags >> 8 ) == 5 ) /* End of font mark */ | |||
break; | |||
+ if ( pfb_pos + 6 > pfb_len + 2 ) | |||
+ goto Exit2; | |||
pfb_data[pfb_pos++] = 0x80; | |||
type = flags >> 8; | |||
@@ -1553,12 +1557,18 @@ | |||
} | |||
error = FT_Stream_Read( stream, (FT_Byte *)pfb_data + pfb_pos, rlen ); | |||
+ if ( error ) | |||
+ goto Exit2; | |||
pfb_pos += rlen; | |||
} | |||
+ if ( pfb_pos + 2 > pfb_len + 2 ) | |||
+ goto Exit2; | |||
pfb_data[pfb_pos++] = 0x80; | |||
pfb_data[pfb_pos++] = 3; | |||
+ if ( pfb_lenpos + 3 > pfb_len + 2 ) | |||
+ goto Exit2; | |||
pfb_data[pfb_lenpos ] = (FT_Byte)( len ); | |||
pfb_data[pfb_lenpos + 1] = (FT_Byte)( len >> 8 ); | |||
pfb_data[pfb_lenpos + 2] = (FT_Byte)( len >> 16 ); |
@@ -0,0 +1,31 @@ | |||
--- freetype-2.3.11/src/smooth/ftgrays.c 2009-07-31 18:45:19.000000000 +0200 | |||
+++ freetype-2.3.11/src/smooth/ftgrays.c 2010-07-13 10:26:58.000000000 +0200 | |||
@@ -1189,7 +1189,7 @@ | |||
/* first of all, compute the scanline offset */ | |||
p = (unsigned char*)map->buffer - y * map->pitch; | |||
if ( map->pitch >= 0 ) | |||
- p += ( map->rows - 1 ) * map->pitch; | |||
+ p += (unsigned)( ( map->rows - 1 ) * map->pitch ); | |||
for ( ; count > 0; count--, spans++ ) | |||
{ | |||
--- freetype-2.3.11/src/smooth/ftsmooth.c 2009-07-31 18:45:19.000000000 +0200 | |||
+++ freetype-2.3.11/src/smooth/ftsmooth.c 2010-07-13 10:26:58.000000000 +0200 | |||
@@ -4,7 +4,7 @@ | |||
/* */ | |||
/* Anti-aliasing renderer interface (body). */ | |||
/* */ | |||
-/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2009 by */ | |||
+/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2009, 2010 by */ | |||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ | |||
/* */ | |||
/* This file is part of the FreeType project, and may only be used, */ | |||
@@ -200,7 +200,7 @@ | |||
/* Required check is ( pitch * height < FT_ULONG_MAX ), */ | |||
/* but we care realistic cases only. Always pitch <= width. */ | |||
- if ( width > 0xFFFFU || height > 0xFFFFU ) | |||
+ if ( width > 0x7FFFU || height > 0x7FFFU ) | |||
{ | |||
FT_ERROR(( "ft_smooth_render_generic: glyph too large: %d x %d\n", | |||
width, height )); |
@@ -0,0 +1,23 @@ | |||
--- freetype-2.3.11/src/base/ftobjs.c 2010-07-12 17:03:47.000000000 +0200 | |||
+++ freetype-2.3.11/src/base/ftobjs.c 2010-07-12 17:07:06.000000000 +0200 | |||
@@ -1526,7 +1526,19 @@ | |||
goto Exit; | |||
if ( FT_READ_USHORT( flags ) ) | |||
goto Exit; | |||
- rlen -= 2; /* the flags are part of the resource */ | |||
+ FT_TRACE3(( "POST fragment[%d]: offsets=0x%08x, rlen=0x%08x, flags=0x%04x\n", | |||
+ i, offsets[i], rlen, flags )); | |||
+ | |||
+ if ( ( flags >> 8 ) == 0 ) /* Comment, should not be loaded */ | |||
+ continue; | |||
+ | |||
+ /* the flags are part of the resource, so rlen >= 2. */ | |||
+ /* but some fonts declare rlen = 0 for empty fragment */ | |||
+ if ( rlen > 2 ) | |||
+ rlen -= 2; | |||
+ else | |||
+ rlen = 0; | |||
+ | |||
if ( ( flags >> 8 ) == type ) | |||
len += rlen; | |||
else |
@@ -0,0 +1,13 @@ | |||
--- freetype-2.3.11/src/truetype/ttinterp.c 2009-07-31 18:45:19.000000000 +0200 | |||
+++ freetype-2.3.11/src/truetype/ttinterp.c 2010-07-15 14:44:23.000000000 +0200 | |||
@@ -6466,8 +6466,8 @@ | |||
end_point = CUR.pts.contours[contour] - CUR.pts.first_point; | |||
first_point = point; | |||
- if ( CUR.pts.n_points <= end_point ) | |||
- end_point = CUR.pts.n_points; | |||
+ if ( BOUNDS ( end_point, CUR.pts.n_points ) ) | |||
+ end_point = CUR.pts.n_points - 1; | |||
while ( point <= end_point && ( CUR.pts.tags[point] & mask ) == 0 ) | |||
point++; |
@@ -0,0 +1,11 @@ | |||
--- freetype-2.3.11/src/base/ftstream.c 2009-08-03 19:51:40.000000000 +0200 | |||
+++ freetype-2.3.11/src/base/ftstream.c 2010-09-30 13:46:08.000000000 +0200 | |||
@@ -275,7 +275,7 @@ | |||
{ | |||
/* check current and new position */ | |||
if ( stream->pos >= stream->size || | |||
- stream->pos + count > stream->size ) | |||
+ stream->size - stream->pos < count ) | |||
{ | |||
FT_ERROR(( "FT_Stream_EnterFrame:" | |||
" invalid i/o; pos = 0x%lx, count = %lu, size = 0x%lx\n", |
@@ -0,0 +1,41 @@ | |||
--- freetype-2.3.11/src/type42/t42parse.c 2009-07-03 15:28:24.000000000 +0200 | |||
+++ freetype-2.3.11/src/type42/t42parse.c 2010-09-23 12:15:56.000000000 +0200 | |||
@@ -4,7 +4,7 @@ | |||
/* */ | |||
/* Type 42 font parser (body). */ | |||
/* */ | |||
-/* Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ | |||
+/* Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 by */ | |||
/* Roberto Alameda. */ | |||
/* */ | |||
/* This file is part of the FreeType project, and may only be used, */ | |||
@@ -575,6 +575,12 @@ | |||
} | |||
string_size = T1_ToInt( parser ); | |||
+ if ( string_size < 0 ) | |||
+ { | |||
+ FT_ERROR(( "t42_parse_sfnts: invalid string size\n" )); | |||
+ error = T42_Err_Invalid_File_Format; | |||
+ goto Fail; | |||
+ } | |||
T1_Skip_PS_Token( parser ); /* `RD' */ | |||
if ( parser->root.error ) | |||
@@ -582,13 +588,14 @@ | |||
string_buf = parser->root.cursor + 1; /* one space after `RD' */ | |||
- parser->root.cursor += string_size + 1; | |||
- if ( parser->root.cursor >= limit ) | |||
+ if ( limit - parser->root.cursor < string_size ) | |||
{ | |||
FT_ERROR(( "t42_parse_sfnts: too many binary data\n" )); | |||
error = T42_Err_Invalid_File_Format; | |||
goto Fail; | |||
} | |||
+ else | |||
+ parser->root.cursor += string_size + 1; | |||
} | |||
if ( !string_buf ) |
@@ -0,0 +1,21 @@ | |||
--- freetype-2.3.11/src/base/ftobjs.c 2010-09-30 13:58:50.000000000 +0200 | |||
+++ freetype-2.3.11/src/base/ftobjs.c 2010-09-30 13:59:31.000000000 +0200 | |||
@@ -1529,6 +1529,7 @@ | |||
FT_TRACE3(( "POST fragment[%d]: offsets=0x%08x, rlen=0x%08x, flags=0x%04x\n", | |||
i, offsets[i], rlen, flags )); | |||
+ /* postpone the check of rlen longer than buffer until FT_Stream_Read() */ | |||
if ( ( flags >> 8 ) == 0 ) /* Comment, should not be loaded */ | |||
continue; | |||
@@ -1568,6 +1569,10 @@ | |||
pfb_data[pfb_pos++] = 0; | |||
} | |||
+ error = FT_Err_Cannot_Open_Resource; | |||
+ if ( pfb_pos > pfb_len || pfb_pos + rlen > pfb_len ) | |||
+ goto Exit2; | |||
+ | |||
error = FT_Stream_Read( stream, (FT_Byte *)pfb_data + pfb_pos, rlen ); | |||
if ( error ) | |||
goto Exit2; |
@@ -0,0 +1,37 @@ | |||
--- freetype-2.3.11/src/base/ftstream.c 2010-09-30 14:12:38.000000000 +0200 | |||
+++ freetype-2.3.11/src/base/ftstream.c 2010-09-30 14:12:59.000000000 +0200 | |||
@@ -59,8 +59,17 @@ | |||
{ | |||
FT_Error error = FT_Err_Ok; | |||
+ /* note that seeking to the first position after the file is valid */ | |||
+ if ( pos > stream->size ) | |||
+ { | |||
+ FT_ERROR(( "FT_Stream_Seek:" | |||
+ " invalid i/o; pos = 0x%lx, size = 0x%lx\n", | |||
+ pos, stream->size )); | |||
- if ( stream->read ) | |||
+ error = FT_Err_Invalid_Stream_Operation; | |||
+ } | |||
+ | |||
+ if ( !error && stream->read ) | |||
{ | |||
if ( stream->read( stream, pos, 0, 0 ) ) | |||
{ | |||
@@ -71,15 +80,6 @@ | |||
error = FT_Err_Invalid_Stream_Operation; | |||
} | |||
} | |||
- /* note that seeking to the first position after the file is valid */ | |||
- else if ( pos > stream->size ) | |||
- { | |||
- FT_ERROR(( "FT_Stream_Seek:" | |||
- " invalid i/o; pos = 0x%lx, size = 0x%lx\n", | |||
- pos, stream->size )); | |||
- | |||
- error = FT_Err_Invalid_Stream_Operation; | |||
- } | |||
if ( !error ) | |||
stream->pos = pos; |
@@ -0,0 +1,20 @@ | |||
--- freetype-2.3.11/src/truetype/ttgxvar.c.orig 2009-07-31 18:45:19.000000000 +0200 | |||
+++ freetype-2.3.11/src/truetype/ttgxvar.c 2010-10-22 08:52:37.000000000 +0200 | |||
@@ -157,7 +157,7 @@ | |||
runcnt = runcnt & GX_PT_POINT_RUN_COUNT_MASK; | |||
first = points[i++] = FT_GET_USHORT(); | |||
- if ( runcnt < 1 ) | |||
+ if ( runcnt < 1 || i + runcnt >= n ) | |||
goto Exit; | |||
/* first point not included in runcount */ | |||
@@ -168,7 +168,7 @@ | |||
{ | |||
first = points[i++] = FT_GET_BYTE(); | |||
- if ( runcnt < 1 ) | |||
+ if ( runcnt < 1 || i + runcnt >= n ) | |||
goto Exit; | |||
for ( j = 0; j < runcnt; ++j ) |
@@ -0,0 +1,108 @@ | |||
--- freetype-2.3.11/src/psaux/t1decode.c 2009-09-29 19:51:31.000000000 +0200 | |||
+++ freetype-2.3.11/src/psaux/t1decode.c 2011-07-20 14:39:24.000000000 +0200 | |||
@@ -4,7 +4,7 @@ | |||
/* */ | |||
/* PostScript Type 1 decoding routines (body). */ | |||
/* */ | |||
-/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ | |||
+/* Copyright 2000-2011 by */ | |||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ | |||
/* */ | |||
/* This file is part of the FreeType project, and may only be used, */ | |||
@@ -27,6 +27,8 @@ | |||
#include "psauxerr.h" | |||
+/* ensure proper sign extension */ | |||
+#define Fix2Int( f ) ( (FT_Int)(FT_Short)( (f) >> 16 ) ) | |||
/*************************************************************************/ | |||
/* */ | |||
@@ -665,7 +667,7 @@ | |||
if ( large_int ) | |||
FT_TRACE4(( " %ld", value )); | |||
else | |||
- FT_TRACE4(( " %ld", (FT_Int32)( value >> 16 ) )); | |||
+ FT_TRACE4(( " %ld", Fix2Int( value ) )); | |||
#endif | |||
*top++ = value; | |||
@@ -687,8 +689,8 @@ | |||
top -= 2; | |||
- subr_no = (FT_Int)( top[1] >> 16 ); | |||
- arg_cnt = (FT_Int)( top[0] >> 16 ); | |||
+ subr_no = Fix2Int( top[1] ); | |||
+ arg_cnt = Fix2Int( top[0] ); | |||
/***********************************************************/ | |||
/* */ | |||
@@ -861,7 +863,7 @@ | |||
if ( arg_cnt != 1 || blend == NULL ) | |||
goto Unexpected_OtherSubr; | |||
- idx = (FT_Int)( top[0] >> 16 ); | |||
+ idx = Fix2Int( top[0] ); | |||
if ( idx < 0 || | |||
idx + blend->num_designs > decoder->len_buildchar ) | |||
@@ -929,7 +931,7 @@ | |||
if ( arg_cnt != 2 || blend == NULL ) | |||
goto Unexpected_OtherSubr; | |||
- idx = (FT_Int)( top[1] >> 16 ); | |||
+ idx = Fix2Int( top[1] ); | |||
if ( idx < 0 || (FT_UInt) idx >= decoder->len_buildchar ) | |||
goto Unexpected_OtherSubr; | |||
@@ -950,7 +952,7 @@ | |||
if ( arg_cnt != 1 || blend == NULL ) | |||
goto Unexpected_OtherSubr; | |||
- idx = (FT_Int)( top[0] >> 16 ); | |||
+ idx = Fix2Int( top[0] ); | |||
if ( idx < 0 || (FT_UInt) idx >= decoder->len_buildchar ) | |||
goto Unexpected_OtherSubr; | |||
@@ -1008,11 +1010,15 @@ | |||
break; | |||
default: | |||
- FT_ERROR(( "t1_decoder_parse_charstrings:" | |||
- " unknown othersubr [%d %d], wish me luck\n", | |||
- arg_cnt, subr_no )); | |||
- unknown_othersubr_result_cnt = arg_cnt; | |||
- break; | |||
+ if ( arg_cnt >= 0 && subr_no >= 0 ) | |||
+ { | |||
+ FT_ERROR(( "t1_decoder_parse_charstrings:" | |||
+ " unknown othersubr [%d %d], wish me luck\n", | |||
+ arg_cnt, subr_no )); | |||
+ unknown_othersubr_result_cnt = arg_cnt; | |||
+ break; | |||
+ } | |||
+ /* fall through */ | |||
Unexpected_OtherSubr: | |||
FT_ERROR(( "t1_decoder_parse_charstrings:" | |||
@@ -1138,8 +1144,8 @@ | |||
top[0], | |||
top[1], | |||
top[2], | |||
- (FT_Int)( top[3] >> 16 ), | |||
- (FT_Int)( top[4] >> 16 ) ); | |||
+ Fix2Int( top[3] ), | |||
+ Fix2Int( top[4] ) ); | |||
case op_sbw: | |||
FT_TRACE4(( " sbw" )); | |||
@@ -1313,7 +1319,7 @@ | |||
FT_TRACE4(( " callsubr" )); | |||
- idx = (FT_Int)( top[0] >> 16 ); | |||
+ idx = Fix2Int( top[0] ); | |||
if ( idx < 0 || idx >= (FT_Int)decoder->num_subrs ) | |||
{ | |||
FT_ERROR(( "t1_decoder_parse_charstrings:" |
@@ -0,0 +1,92 @@ | |||
--- freetype-2.3.11/src/base/ftbitmap.c 2009-07-31 18:45:18.000000000 +0200 | |||
+++ freetype-2.3.11/src/base/ftbitmap.c 2011-10-19 12:25:26.000000000 +0200 | |||
@@ -4,7 +4,7 @@ | |||
/* */ | |||
/* FreeType utility functions for bitmaps (body). */ | |||
/* */ | |||
-/* Copyright 2004, 2005, 2006, 2007, 2008, 2009 by */ | |||
+/* Copyright 2004-2009, 2011 by */ | |||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ | |||
/* */ | |||
/* This file is part of the FreeType project, and may only be used, */ | |||
@@ -417,6 +417,10 @@ | |||
target->pitch = source->width + pad; | |||
+ if ( target->pitch > 0 && | |||
+ target->rows > FT_ULONG_MAX / target->pitch ) | |||
+ return FT_Err_Invalid_Argument; | |||
+ | |||
if ( target->rows * target->pitch > old_size && | |||
FT_QREALLOC( target->buffer, | |||
old_size, target->rows * target->pitch ) ) | |||
--- freetype-2.3.11/src/psaux/t1decode.c 2011-10-19 12:25:26.000000000 +0200 | |||
+++ freetype-2.3.11/src/psaux/t1decode.c 2011-10-19 12:25:26.000000000 +0200 | |||
@@ -748,6 +748,13 @@ | |||
if ( arg_cnt != 0 ) | |||
goto Unexpected_OtherSubr; | |||
+ if ( decoder->flex_state == 0 ) | |||
+ { | |||
+ FT_ERROR(( "t1_decoder_parse_charstrings:" | |||
+ " missing flex start\n" )); | |||
+ goto Syntax_Error; | |||
+ } | |||
+ | |||
/* note that we should not add a point for index 0; */ | |||
/* this will move our current position to the flex */ | |||
/* point without adding any point to the outline */ | |||
--- freetype-2.3.11/src/raster/ftrend1.c 2009-07-03 15:28:24.000000000 +0200 | |||
+++ freetype-2.3.11/src/raster/ftrend1.c 2011-10-19 13:26:02.000000000 +0200 | |||
@@ -4,7 +4,7 @@ | |||
/* */ | |||
/* The FreeType glyph rasterizer interface (body). */ | |||
/* */ | |||
-/* Copyright 1996-2001, 2002, 2003, 2005, 2006 by */ | |||
+/* Copyright 1996-2003, 2005, 2006, 2011 by */ | |||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ | |||
/* */ | |||
/* This file is part of the FreeType project, and may only be used, */ | |||
@@ -25,6 +25,7 @@ | |||
#include "rasterrs.h" | |||
+#define FT_USHORT_MAX USHRT_MAX | |||
/* initialize renderer -- init its raster */ | |||
static FT_Error | |||
@@ -168,6 +169,13 @@ | |||
width = (FT_UInt)( ( cbox.xMax - cbox.xMin ) >> 6 ); | |||
height = (FT_UInt)( ( cbox.yMax - cbox.yMin ) >> 6 ); | |||
+ | |||
+ if ( width > FT_USHORT_MAX || height > FT_USHORT_MAX ) | |||
+ { | |||
+ error = Raster_Err_Invalid_Argument; | |||
+ goto Exit; | |||
+ } | |||
+ | |||
bitmap = &slot->bitmap; | |||
memory = render->root.memory; | |||
--- freetype-2.3.11/src/truetype/ttgxvar.c 2011-10-19 12:25:26.000000000 +0200 | |||
+++ freetype-2.3.11/src/truetype/ttgxvar.c 2011-10-19 12:25:26.000000000 +0200 | |||
@@ -4,7 +4,7 @@ | |||
/* */ | |||
/* TrueType GX Font Variation loader */ | |||
/* */ | |||
-/* Copyright 2004, 2005, 2006, 2007, 2008, 2009 by */ | |||
+/* Copyright 2004-2011 by */ | |||
/* David Turner, Robert Wilhelm, Werner Lemberg, and George Williams. */ | |||
/* */ | |||
/* This file is part of the FreeType project, and may only be used, */ | |||
@@ -1473,6 +1473,9 @@ | |||
{ | |||
for ( j = 0; j < point_count; ++j ) | |||
{ | |||
+ if ( localpoints[j] >= n_points ) | |||
+ continue; | |||
+ | |||
delta_xy[localpoints[j]].x += FT_MulFix( deltas_x[j], apply ); | |||
delta_xy[localpoints[j]].y += FT_MulFix( deltas_y[j], apply ); | |||
} |
@@ -0,0 +1,76 @@ | |||
--- freetype-2.3.11/src/cid/cidload.c 2009-07-03 15:28:24.000000000 +0200 | |||
+++ freetype-2.3.11/src/cid/cidload.c 2011-11-15 12:58:41.000000000 +0100 | |||
@@ -4,7 +4,7 @@ | |||
/* */ | |||
/* CID-keyed Type1 font loader (body). */ | |||
/* */ | |||
-/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2009 by */ | |||
+/* Copyright 1996-2006, 2009, 2011 by */ | |||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ | |||
/* */ | |||
/* This file is part of the FreeType project, and may only be used, */ | |||
@@ -110,7 +110,7 @@ | |||
CID_FaceDict dict; | |||
- if ( parser->num_dict < 0 ) | |||
+ if ( parser->num_dict < 0 || parser->num_dict >= cid->num_dicts ) | |||
{ | |||
FT_ERROR(( "cid_load_keyword: invalid use of `%s'\n", | |||
keyword->ident )); | |||
@@ -158,7 +158,7 @@ | |||
FT_Fixed temp_scale; | |||
- if ( parser->num_dict >= 0 ) | |||
+ if ( parser->num_dict >= 0 && parser->num_dict < face->cid.num_dicts ) | |||
{ | |||
dict = face->cid.font_dicts + parser->num_dict; | |||
matrix = &dict->font_matrix; | |||
@@ -249,7 +249,7 @@ | |||
CID_FaceDict dict; | |||
- if ( parser->num_dict >= 0 ) | |||
+ if ( parser->num_dict >= 0 && parser->num_dict < face->cid.num_dicts ) | |||
{ | |||
dict = face->cid.font_dicts + parser->num_dict; | |||
@@ -413,12 +413,25 @@ | |||
FT_Byte* p; | |||
+ /* Check for possible overflow. */ | |||
+ if ( num_subrs == FT_UINT_MAX ) | |||
+ { | |||
+ error = CID_Err_Syntax_Error; | |||
+ goto Fail; | |||
+ } | |||
+ | |||
/* reallocate offsets array if needed */ | |||
if ( num_subrs + 1 > max_offsets ) | |||
{ | |||
FT_UInt new_max = FT_PAD_CEIL( num_subrs + 1, 4 ); | |||
+ if ( new_max <= max_offsets ) | |||
+ { | |||
+ error = CID_Err_Syntax_Error; | |||
+ goto Fail; | |||
+ } | |||
+ | |||
if ( FT_RENEW_ARRAY( offsets, max_offsets, new_max ) ) | |||
goto Fail; | |||
@@ -436,6 +449,11 @@ | |||
FT_FRAME_EXIT(); | |||
+ /* offsets must be ordered */ | |||
+ for ( count = 1; count <= num_subrs; count++ ) | |||
+ if ( offsets[count - 1] > offsets[count] ) | |||
+ goto Fail; | |||
+ | |||
/* now, compute the size of subrs charstrings, */ | |||
/* allocate, and read them */ | |||
data_len = offsets[num_subrs] - offsets[0]; |
@@ -0,0 +1,20 @@ | |||
--- freetype-2.3.11/src/bdf/bdflib.c 2009-09-12 23:14:25.000000000 +0200 | |||
+++ freetype-2.3.11/src/bdf/bdflib.c 2012-03-28 10:19:23.000000000 +0200 | |||
@@ -1,6 +1,6 @@ | |||
/* | |||
* Copyright 2000 Computing Research Labs, New Mexico State University | |||
- * Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 | |||
+ * Copyright 2001-2012 | |||
* Francesco Zappa Nardelli | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
@@ -1235,7 +1235,8 @@ | |||
ep = line + linelen; | |||
/* Trim the leading whitespace if it exists. */ | |||
- *sp++ = 0; | |||
+ if ( *sp ) | |||
+ *sp++ = 0; | |||
while ( *sp && | |||
( *sp == ' ' || *sp == '\t' ) ) | |||
sp++; |
@@ -0,0 +1,43 @@ | |||
--- freetype-2.3.11/src/bdf/bdflib.c 2012-03-28 10:20:31.000000000 +0200 | |||
+++ freetype-2.3.11/src/bdf/bdflib.c 2012-03-28 10:22:28.000000000 +0200 | |||
@@ -1092,6 +1092,7 @@ | |||
#define ACMSG13 "Glyph %ld extra rows removed.\n" | |||
#define ACMSG14 "Glyph %ld extra columns removed.\n" | |||
#define ACMSG15 "Incorrect glyph count: %ld indicated but %ld found.\n" | |||
+#define ACMSG16 "Glyph %ld missing columns padded with zero bits.\n" | |||
/* Error messages. */ | |||
#define ERRMSG1 "[line %ld] Missing \"%s\" line.\n" | |||
@@ -1695,18 +1696,31 @@ | |||
for ( i = 0; i < nibbles; i++ ) | |||
{ | |||
c = line[i]; | |||
+ if ( !c ) | |||
+ break; | |||
*bp = (FT_Byte)( ( *bp << 4 ) + a2i[c] ); | |||
if ( i + 1 < nibbles && ( i & 1 ) ) | |||
*++bp = 0; | |||
} | |||
+ /* If any line has not enough columns, */ | |||
+ /* indicate they have been padded with zero bits. */ | |||
+ if ( i < nibbles && | |||
+ !( p->flags & _BDF_GLYPH_WIDTH_CHECK ) ) | |||
+ { | |||
+ FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG16, glyph->encoding )); | |||
+ p->flags |= _BDF_GLYPH_WIDTH_CHECK; | |||
+ font->modified = 1; | |||
+ } | |||
+ | |||
/* Remove possible garbage at the right. */ | |||
mask_index = ( glyph->bbx.width * p->font->bpp ) & 7; | |||
if ( glyph->bbx.width ) | |||
*bp &= nibble_mask[mask_index]; | |||
/* If any line has extra columns, indicate they have been removed. */ | |||
- if ( ( line[nibbles] == '0' || a2i[(int)line[nibbles]] != 0 ) && | |||
+ if ( i == nibbles && | |||
+ ( line[nibbles] == '0' || a2i[(int)line[nibbles]] != 0 ) && | |||
!( p->flags & _BDF_GLYPH_WIDTH_CHECK ) ) | |||
{ | |||
FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG14, glyph->encoding )); |
@@ -0,0 +1,21 @@ | |||
--- freetype-2.3.11/src/pcf/pcfread.c 2009-10-10 19:32:28.000000000 +0200 | |||
+++ freetype-2.3.11/src/pcf/pcfread.c 2012-03-28 10:29:54.000000000 +0200 | |||
@@ -2,7 +2,7 @@ | |||
FreeType font driver for pcf fonts | |||
- Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by | |||
+ Copyright 2000-2010, 2012 by | |||
Francesco Zappa Nardelli | |||
Permission is hereby granted, free of charge, to any person obtaining a copy | |||
@@ -495,7 +495,8 @@ THE SOFTWARE. | |||
goto Bail; | |||
} | |||
- if ( FT_NEW_ARRAY( strings, string_size ) ) | |||
+ /* allocate one more byte so that we have a final null byte */ | |||
+ if ( FT_NEW_ARRAY( strings, string_size + 1 ) ) | |||
goto Bail; | |||
error = FT_Stream_Read( stream, (FT_Byte*)strings, string_size ); |
@@ -0,0 +1,40 @@ | |||
--- freetype-2.3.11/src/smooth/ftsmooth.c 2012-03-28 10:30:52.000000000 +0200 | |||
+++ freetype-2.3.11/src/smooth/ftsmooth.c 2012-03-28 10:33:13.000000000 +0200 | |||
@@ -4,7 +4,7 @@ | |||
/* */ | |||
/* Anti-aliasing renderer interface (body). */ | |||
/* */ | |||
-/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2009, 2010 by */ | |||
+/* Copyright 2000-2006, 2009-2012 by */ | |||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ | |||
/* */ | |||
/* This file is part of the FreeType project, and may only be used, */ | |||
@@ -105,7 +105,7 @@ | |||
FT_Error error; | |||
FT_Outline* outline = NULL; | |||
FT_BBox cbox; | |||
- FT_UInt width, height, height_org, width_org, pitch; | |||
+ FT_Pos width, height, height_org, width_org, pitch; | |||
FT_Bitmap* bitmap; | |||
FT_Memory memory; | |||
FT_Int hmul = mode == FT_RENDER_MODE_LCD; | |||
@@ -140,8 +140,8 @@ | |||
cbox.xMax = FT_PIX_CEIL( cbox.xMax ); | |||
cbox.yMax = FT_PIX_CEIL( cbox.yMax ); | |||
- width = (FT_UInt)( ( cbox.xMax - cbox.xMin ) >> 6 ); | |||
- height = (FT_UInt)( ( cbox.yMax - cbox.yMin ) >> 6 ); | |||
+ width = ( cbox.xMax - cbox.xMin ) >> 6; | |||
+ height = ( cbox.yMax - cbox.yMin ) >> 6; | |||
bitmap = &slot->bitmap; | |||
memory = render->root.memory; | |||
@@ -200,7 +200,7 @@ | |||
/* Required check is ( pitch * height < FT_ULONG_MAX ), */ | |||
/* but we care realistic cases only. Always pitch <= width. */ | |||
- if ( width > 0x7FFFU || height > 0x7FFFU ) | |||
+ if ( width > 0x7FFF || height > 0x7FFF ) | |||
{ | |||
FT_ERROR(( "ft_smooth_render_generic: glyph too large: %d x %d\n", | |||
width, height )); |
@@ -0,0 +1,130 @@ | |||
--- freetype-2.3.11/src/psaux/psobjs.c 2009-07-31 18:45:18.000000000 +0200 | |||
+++ freetype-2.3.11/src/psaux/psobjs.c 2012-04-03 13:14:05.000000000 +0200 | |||
@@ -4,7 +4,7 @@ | |||
/* */ | |||
/* Auxiliary functions for PostScript fonts (body). */ | |||
/* */ | |||
-/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ | |||
+/* Copyright 1996-2012 by */ | |||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ | |||
/* */ | |||
/* This file is part of the FreeType project, and may only be used, */ | |||
@@ -589,7 +589,7 @@ | |||
} | |||
Exit: | |||
- if ( cur == parser->cursor ) | |||
+ if ( cur < limit && cur == parser->cursor ) | |||
{ | |||
FT_ERROR(( "ps_parser_skip_PS_token:" | |||
" current token is `%c' which is self-delimiting\n" | |||
--- freetype-2.3.11/src/type1/t1load.c 2009-09-01 08:07:32.000000000 +0200 | |||
+++ freetype-2.3.11/src/type1/t1load.c 2012-04-03 13:14:30.000000000 +0200 | |||
@@ -71,6 +71,13 @@ | |||
#include "t1errors.h" | |||
+#ifdef FT_CONFIG_OPTION_INCREMENTAL | |||
+#define IS_INCREMENTAL ( face->root.internal->incremental_interface != 0 ) | |||
+#else | |||
+#define IS_INCREMENTAL 0 | |||
+#endif | |||
+ | |||
+ | |||
/*************************************************************************/ | |||
/* */ | |||
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */ | |||
@@ -1027,7 +1034,8 @@ | |||
static int | |||
read_binary_data( T1_Parser parser, | |||
FT_Long* size, | |||
- FT_Byte** base ) | |||
+ FT_Byte** base, | |||
+ FT_Bool incremental ) | |||
{ | |||
FT_Byte* cur; | |||
FT_Byte* limit = parser->root.limit; | |||
@@ -1057,8 +1065,12 @@ | |||
return !parser->root.error; | |||
} | |||
- FT_ERROR(( "read_binary_data: invalid size field\n" )); | |||
- parser->root.error = T1_Err_Invalid_File_Format; | |||
+ if( !incremental ) | |||
+ { | |||
+ FT_ERROR(( "read_binary_data: invalid size field\n" )); | |||
+ parser->root.error = T1_Err_Invalid_File_Format; | |||
+ } | |||
+ | |||
return 0; | |||
} | |||
@@ -1379,15 +1391,17 @@ | |||
FT_Byte* base; | |||
- /* If the next token isn't `dup' we are done. */ | |||
- if ( ft_strncmp( (char*)parser->root.cursor, "dup", 3 ) != 0 ) | |||
+ /* If we are out of data, or if the next token isn't `dup', */ | |||
+ /* we are done. */ | |||
+ if ( parser->root.cursor + 4 >= parser->root.limit || | |||
+ ft_strncmp( (char*)parser->root.cursor, "dup", 3 ) != 0 ) | |||
break; | |||
T1_Skip_PS_Token( parser ); /* `dup' */ | |||
idx = T1_ToInt( parser ); | |||
- if ( !read_binary_data( parser, &size, &base ) ) | |||
+ if ( !read_binary_data( parser, &size, &base, IS_INCREMENTAL ) ) | |||
return; | |||
/* The binary string is followed by one token, e.g. `NP' */ | |||
@@ -1399,7 +1413,8 @@ | |||
return; | |||
T1_Skip_Spaces ( parser ); | |||
- if ( ft_strncmp( (char*)parser->root.cursor, "put", 3 ) == 0 ) | |||
+ if ( parser->root.cursor + 4 < parser->root.limit && | |||
+ ft_strncmp( (char*)parser->root.cursor, "put", 3 ) == 0 ) | |||
{ | |||
T1_Skip_PS_Token( parser ); /* skip `put' */ | |||
T1_Skip_Spaces ( parser ); | |||
@@ -1572,7 +1587,7 @@ | |||
cur++; /* skip `/' */ | |||
len = parser->root.cursor - cur; | |||
- if ( !read_binary_data( parser, &size, &base ) ) | |||
+ if ( !read_binary_data( parser, &size, &base, IS_INCREMENTAL ) ) | |||
return; | |||
/* for some non-standard fonts like `Optima' which provides */ | |||
@@ -1861,7 +1876,7 @@ | |||
parser->root.cursor = start_binary; | |||
- if ( !read_binary_data( parser, &s, &b ) ) | |||
+ if ( !read_binary_data( parser, &s, &b, IS_INCREMENTAL ) ) | |||
return T1_Err_Invalid_File_Format; | |||
have_integer = 0; | |||
} | |||
@@ -1874,7 +1889,7 @@ | |||
parser->root.cursor = start_binary; | |||
- if ( !read_binary_data( parser, &s, &b ) ) | |||
+ if ( !read_binary_data( parser, &s, &b, IS_INCREMENTAL ) ) | |||
return T1_Err_Invalid_File_Format; | |||
have_integer = 0; | |||
} | |||
@@ -2148,9 +2163,7 @@ | |||
type1->subrs_len = loader.subrs.lengths; | |||
} | |||
-#ifdef FT_CONFIG_OPTION_INCREMENTAL | |||
- if ( !face->root.internal->incremental_interface ) | |||
-#endif | |||
+ if ( !IS_INCREMENTAL ) | |||
if ( !loader.charstrings.init ) | |||
{ | |||
FT_ERROR(( "T1_Open_Face: no `/CharStrings' array in face\n" )); |
@@ -0,0 +1,26 @@ | |||
--- freetype-2.3.11/src/type1/t1parse.c 2009-07-03 15:28:24.000000000 +0200 | |||
+++ freetype-2.3.11/src/type1/t1parse.c 2012-03-28 10:39:25.000000000 +0200 | |||
@@ -4,7 +4,7 @@ | |||
/* */ | |||
/* Type 1 parser (body). */ | |||
/* */ | |||
-/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2008, 2009 by */ | |||
+/* Copyright 1996-2005, 2008, 2009, 2012 by */ | |||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ | |||
/* */ | |||
/* This file is part of the FreeType project, and may only be used, */ | |||
@@ -464,6 +464,14 @@ | |||
/* we now decrypt the encoded binary private dictionary */ | |||
psaux->t1_decrypt( parser->private_dict, parser->private_len, 55665U ); | |||
+ if ( parser->private_len < 4 ) | |||
+ { | |||
+ FT_ERROR(( "T1_Get_Private_Dict:" | |||
+ " invalid private dictionary section\n" )); | |||
+ error = T1_Err_Invalid_File_Format; | |||
+ goto Fail; | |||
+ } | |||
+ | |||
/* replace the four random bytes at the beginning with whitespace */ | |||
parser->private_dict[0] = ' '; | |||
parser->private_dict[1] = ' '; |
@@ -0,0 +1,49 @@ | |||
--- freetype-2.3.11/src/bdf/bdflib.c 2012-03-28 10:40:25.000000000 +0200 | |||
+++ freetype-2.3.11/src/bdf/bdflib.c 2012-03-28 10:44:30.000000000 +0200 | |||
@@ -1736,12 +1736,7 @@ | |||
if ( ft_memcmp( line, "SWIDTH", 6 ) == 0 ) | |||
{ | |||
if ( !( p->flags & _BDF_ENCODING ) ) | |||
- { | |||
- /* Missing ENCODING field. */ | |||
- FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "ENCODING" )); | |||
- error = BDF_Err_Missing_Encoding_Field; | |||
- goto Exit; | |||
- } | |||
+ goto Missing_Encoding; | |||
error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); | |||
if ( error ) | |||
@@ -1756,6 +1751,9 @@ | |||
/* Expect the DWIDTH (scalable width) field next. */ | |||
if ( ft_memcmp( line, "DWIDTH", 6 ) == 0 ) | |||
{ | |||
+ if ( !( p->flags & _BDF_ENCODING ) ) | |||
+ goto Missing_Encoding; | |||
+ | |||
error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); | |||
if ( error ) | |||
goto Exit; | |||
@@ -1781,6 +1779,9 @@ | |||
/* Expect the BBX field next. */ | |||
if ( ft_memcmp( line, "BBX", 3 ) == 0 ) | |||
{ | |||
+ if ( !( p->flags & _BDF_ENCODING ) ) | |||
+ goto Missing_Encoding; | |||
+ | |||
error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); | |||
if ( error ) | |||
goto Exit; | |||
@@ -1880,6 +1881,12 @@ | |||
} | |||
error = BDF_Err_Invalid_File_Format; | |||
+ goto Exit; | |||
+ | |||
+ Missing_Encoding: | |||
+ /* Missing ENCODING field. */ | |||
+ FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "ENCODING" )); | |||
+ error = BDF_Err_Missing_Encoding_Field; | |||
Exit: | |||
return error; |
@@ -0,0 +1,11 @@ | |||
--- freetype-2.3.11/src/bdf/bdflib.c 2012-03-28 10:46:09.000000000 +0200 | |||
+++ freetype-2.3.11/src/bdf/bdflib.c 2012-03-28 10:45:50.000000000 +0200 | |||
@@ -424,7 +424,7 @@ | |||
if ( num_items > list->size ) | |||
{ | |||
unsigned long oldsize = list->size; /* same as _bdf_list_t.size */ | |||
- unsigned long newsize = oldsize + ( oldsize >> 1 ) + 4; | |||
+ unsigned long newsize = oldsize + ( oldsize >> 1 ) + 5; | |||
unsigned long bigsize = (unsigned long)( FT_INT_MAX / sizeof ( char* ) ); | |||
FT_Memory memory = list->memory; | |||
@@ -0,0 +1,33 @@ | |||
--- freetype-2.3.11/src/bdf/bdflib.c 2012-03-28 10:49:56.000000000 +0200 | |||
+++ freetype-2.3.11/src/bdf/bdflib.c 2012-03-28 10:51:40.000000000 +0200 | |||
@@ -785,7 +785,7 @@ | |||
}; | |||
-#define isdigok( m, d ) (m[(d) >> 3] & ( 1 << ( (d) & 7 ) ) ) | |||
+#define isdigok( m, d ) (m[(unsigned char)(d) >> 3] & ( 1 << ( (d) & 7 ) ) ) | |||
/* Routine to convert an ASCII string into an unsigned long integer. */ | |||
@@ -1696,7 +1696,7 @@ | |||
for ( i = 0; i < nibbles; i++ ) | |||
{ | |||
c = line[i]; | |||
- if ( !c ) | |||
+ if ( !isdigok( hdigits, c ) ) | |||
break; | |||
*bp = (FT_Byte)( ( *bp << 4 ) + a2i[c] ); | |||
if ( i + 1 < nibbles && ( i & 1 ) ) | |||
@@ -1719,9 +1719,9 @@ | |||
*bp &= nibble_mask[mask_index]; | |||
/* If any line has extra columns, indicate they have been removed. */ | |||
- if ( i == nibbles && | |||
- ( line[nibbles] == '0' || a2i[(int)line[nibbles]] != 0 ) && | |||
- !( p->flags & _BDF_GLYPH_WIDTH_CHECK ) ) | |||
+ if ( i == nibbles && | |||
+ isdigok( hdigits, line[nibbles] ) && | |||
+ !( p->flags & _BDF_GLYPH_WIDTH_CHECK ) ) | |||
{ | |||
FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG14, glyph->encoding )); | |||
p->flags |= _BDF_GLYPH_WIDTH_CHECK; |
@@ -0,0 +1,53 @@ | |||
--- freetype-2.3.11/src/psaux/psconv.c 2009-07-31 18:45:18.000000000 +0200 | |||
+++ freetype-2.3.11/src/psaux/psconv.c 2012-03-28 10:55:16.000000000 +0200 | |||
@@ -4,7 +4,7 @@ | |||
/* */ | |||
/* Some convenience conversions (body). */ | |||
/* */ | |||
-/* Copyright 2006, 2008, 2009 by */ | |||
+/* Copyright 2006, 2008, 2009, 2012 by */ | |||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ | |||
/* */ | |||
/* This file is part of the FreeType project, and may only be used, */ | |||
@@ -79,7 +79,7 @@ | |||
FT_Bool sign = 0; | |||
- if ( p == limit || base < 2 || base > 36 ) | |||
+ if ( p >= limit || base < 2 || base > 36 ) | |||
return 0; | |||
if ( *p == '-' || *p == '+' ) | |||
@@ -150,7 +150,7 @@ | |||
FT_Bool sign = 0; | |||
- if ( p == limit ) | |||
+ if ( p >= limit ) | |||
return 0; | |||
if ( *p == '-' || *p == '+' ) | |||
@@ -346,7 +346,11 @@ | |||
#if 1 | |||
- p = *cursor; | |||
+ p = *cursor; | |||
+ | |||
+ if ( p >= limit ) | |||
+ return 0; | |||
+ | |||
if ( n > (FT_UInt)( limit - p ) ) | |||
n = (FT_UInt)( limit - p ); | |||
@@ -434,6 +438,10 @@ | |||
#if 1 | |||
p = *cursor; | |||
+ | |||
+ if ( p >= limit ) | |||
+ return 0; | |||
+ | |||
if ( n > (FT_UInt)(limit - p) ) | |||
n = (FT_UInt)(limit - p); | |||
@@ -0,0 +1,17 @@ | |||
--- freetype-2.3.11/src/bdf/bdflib.c 2012-03-28 11:53:32.000000000 +0200 | |||
+++ freetype-2.3.11/src/bdf/bdflib.c 2012-03-28 11:54:12.000000000 +0200 | |||
@@ -520,6 +520,14 @@ | |||
/* Initialize the list. */ | |||
list->used = 0; | |||
+ if ( list->size ) | |||
+ { | |||
+ list->field[0] = (char*)empty; | |||
+ list->field[1] = (char*)empty; | |||
+ list->field[2] = (char*)empty; | |||
+ list->field[3] = (char*)empty; | |||
+ list->field[4] = (char*)empty; | |||
+ } | |||
/* If the line is empty, then simply return. */ | |||
if ( linelen == 0 || line[0] == 0 ) |
@@ -0,0 +1,27 @@ | |||
--- freetype-2.3.11/src/winfonts/winfnt.c 2009-07-31 18:45:19.000000000 +0200 | |||
+++ freetype-2.3.11/src/winfonts/winfnt.c 2012-03-28 11:57:05.000000000 +0200 | |||
@@ -4,7 +4,7 @@ | |||
/* */ | |||
/* FreeType font driver for Windows FNT/FON files */ | |||
/* */ | |||
-/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009 by */ | |||
+/* Copyright 1996-2004, 2006-2012 by */ | |||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ | |||
/* Copyright 2003 Huw D M Davies for Codeweavers */ | |||
/* Copyright 2007 Dmitry Timoshkov for Codeweavers */ | |||
@@ -825,7 +825,14 @@ | |||
root->charmap = root->charmaps[0]; | |||
} | |||
- /* setup remaining flags */ | |||
+ /* set up remaining flags */ | |||
+ | |||
+ if ( font->header.last_char < font->header.first_char ) | |||
+ { | |||
+ FT_TRACE2(( "invalid number of glyphs\n" )); | |||
+ error = FNT_Err_Invalid_File_Format; | |||
+ goto Fail; | |||
+ } | |||
/* reserve one slot for the .notdef glyph at index 0 */ | |||
root->num_glyphs = font->header.last_char - |
@@ -0,0 +1,67 @@ | |||
--- freetype-2.3.11/src/base/ftcalc.c 2009-07-31 18:45:18.000000000 +0200 | |||
+++ freetype-2.3.11/src/base/ftcalc.c 2012-03-28 11:59:17.000000000 +0200 | |||
@@ -4,7 +4,7 @@ | |||
/* */ | |||
/* Arithmetic computations (body). */ | |||
/* */ | |||
-/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008 by */ | |||
+/* Copyright 1996-2006, 2008, 2012 by */ | |||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ | |||
/* */ | |||
/* This file is part of the FreeType project, and may only be used, */ | |||
@@ -307,7 +307,7 @@ | |||
q <<= 1; | |||
r |= lo >> 31; | |||
- if ( r >= (FT_UInt32)y ) | |||
+ if ( r >= y ) | |||
{ | |||
r -= y; | |||
q |= 1; | |||
@@ -373,7 +373,7 @@ | |||
if ( a <= 46340L && b <= 46340L && c <= 176095L && c > 0 ) | |||
a = ( a * b + ( c >> 1 ) ) / c; | |||
- else if ( c > 0 ) | |||
+ else if ( (FT_Int32)c > 0 ) | |||
{ | |||
FT_Int64 temp, temp2; | |||
@@ -412,7 +412,7 @@ | |||
if ( a <= 46340L && b <= 46340L && c > 0 ) | |||
a = a * b / c; | |||
- else if ( c > 0 ) | |||
+ else if ( (FT_Int32)c > 0 ) | |||
{ | |||
FT_Int64 temp; | |||
@@ -544,7 +544,7 @@ | |||
s = (FT_Int32)a; a = FT_ABS( a ); | |||
s ^= (FT_Int32)b; b = FT_ABS( b ); | |||
- if ( b == 0 ) | |||
+ if ( (FT_UInt32)b == 0 ) | |||
{ | |||
/* check for division by 0 */ | |||
q = (FT_UInt32)0x7FFFFFFFL; | |||
@@ -552,15 +552,16 @@ | |||
else if ( ( a >> 16 ) == 0 ) | |||
{ | |||
/* compute result directly */ | |||
- q = (FT_UInt32)( (a << 16) + (b >> 1) ) / (FT_UInt32)b; | |||
+ q = (FT_UInt32)( ( a << 16 ) + ( b >> 1 ) ) / (FT_UInt32)b; | |||
} | |||
else | |||
{ | |||
/* we need more bits; we have to do it by hand */ | |||
FT_Int64 temp, temp2; | |||
- temp.hi = (FT_Int32) (a >> 16); | |||
- temp.lo = (FT_UInt32)(a << 16); | |||
+ | |||
+ temp.hi = (FT_Int32) ( a >> 16 ); | |||
+ temp.lo = (FT_UInt32)( a << 16 ); | |||
temp2.hi = 0; | |||
temp2.lo = (FT_UInt32)( b >> 1 ); | |||
FT_Add64( &temp, &temp2, &temp ); |
@@ -0,0 +1,22 @@ | |||
--- freetype-2.3.11/src/truetype/ttgload.c 2009-09-08 07:06:51.000000000 +0200 | |||
+++ freetype-2.3.11/src/truetype/ttgload.c 2012-03-28 12:01:04.000000000 +0200 | |||
@@ -267,14 +267,17 @@ | |||
if ( n_contours >= 0xFFF || p + ( n_contours + 1 ) * 2 > limit ) | |||
goto Invalid_Outline; | |||
- prev_cont = FT_NEXT_USHORT( p ); | |||
+ prev_cont = FT_NEXT_SHORT( p ); | |||
if ( n_contours > 0 ) | |||
cont[0] = prev_cont; | |||
+ if ( prev_cont < 0 ) | |||
+ goto Invalid_Outline; | |||
+ | |||
for ( cont++; cont < cont_limit; cont++ ) | |||
{ | |||
- cont[0] = FT_NEXT_USHORT( p ); | |||
+ cont[0] = FT_NEXT_SHORT( p ); | |||
if ( cont[0] <= prev_cont ) | |||
{ | |||
/* unordered contours: this is invalid */ |
@@ -0,0 +1,12 @@ | |||
--- freetype-2.3.11/src/base/ftoutln.c 2009-03-14 14:45:26.000000000 +0100 | |||
+++ freetype-2.3.11/src/base/ftoutln.c 2012-04-03 11:03:35.000000000 +0200 | |||
@@ -990,7 +990,8 @@ | |||
int i; | |||
FT_Pos ray_y[3]; | |||
- FT_Orientation result[3]; | |||
+ FT_Orientation result[3] = | |||
+ { FT_ORIENTATION_NONE, FT_ORIENTATION_NONE, FT_ORIENTATION_NONE }; | |||
if ( !outline || outline->n_points <= 0 ) |
@@ -0,0 +1,11 @@ | |||
--- freetype-2.3.11/src/bdf/bdflib.c 2012-04-02 16:24:56.000000000 +0200 | |||
+++ freetype-2.3.11/src/bdf/bdflib.c 2012-04-02 16:25:33.000000000 +0200 | |||
@@ -1870,7 +1870,7 @@ | |||
glyph->bpr = ( glyph->bbx.width * p->font->bpp + 7 ) >> 3; | |||
bitmap_size = glyph->bpr * glyph->bbx.height; | |||
- if ( bitmap_size > 0xFFFFU ) | |||
+ if ( glyph->bpr > 0xFFFFU || bitmap_size > 0xFFFFU ) | |||
{ | |||
FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG4, lineno )); | |||
error = BDF_Err_Bbx_Too_Big; |
@@ -0,0 +1,18 @@ | |||
--- freetype-2.2.1/builds/unix/freetype-config.in.multilib 2006-07-27 18:50:40.000000000 -0400 | |||
+++ freetype-2.2.1/builds/unix/freetype-config.in 2006-07-27 18:58:13.000000000 -0400 | |||
@@ -9,11 +9,11 @@ | |||
# indicate that you have read the license and understand and accept it | |||
# fully. | |||
-prefix=@prefix@ | |||
-exec_prefix=@exec_prefix@ | |||
+prefix=`pkg-config --variable prefix freetype2` | |||
+exec_prefix=`pkg-config --variable exec_prefix freetype2` | |||
exec_prefix_set=no | |||
-includedir=@includedir@ | |||
-libdir=@libdir@ | |||
+includedir=`pkg-config --variable includedir freetype2` | |||
+libdir=`pkg-config --variable libdir freetype2` | |||
enable_shared=@build_libtool_libs@ | |||
wl=@wl@ | |||
hardcode_libdir_flag_spec='@hardcode_libdir_flag_spec@' |
@@ -0,0 +1,21 @@ | |||
commit 532d2051245a1d8afe7ca236f1d966d555bb121a | |||
Author: Dave Airlie <airlied@linux.ie> | |||
Date: Fri Sep 12 17:21:25 2008 +1000 | |||
Revert "intel: sync to vblank by default" | |||
This reverts commit e9bf3e4cc9a7e4bcd4c45bd707541d26ecdf0409. | |||
diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c | |||
index c193830..f02192d 100644 | |||
--- a/src/mesa/drivers/dri/intel/intel_screen.c | |||
+++ b/src/mesa/drivers/dri/intel/intel_screen.c | |||
@@ -55,7 +55,7 @@ PUBLIC const char __driConfigOptions[] = | |||
DRI_CONF_BEGIN | |||
DRI_CONF_SECTION_PERFORMANCE | |||
DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS) | |||
- DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_ALWAYS_SYNC) | |||
+ DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0) | |||
/* Options correspond to DRI_CONF_BO_REUSE_DISABLED, | |||
* DRI_CONF_BO_REUSE_ALL | |||
*/ |
@@ -0,0 +1,14 @@ | |||
diff -up libX11-1.3.1/man/XCreateGC.man.fix-XCreateGC_manpage libX11-1.3.1/man/XCreateGC.man | |||
--- libX11-1.3.1/man/XCreateGC.man.fix-XCreateGC_manpage 2010-04-12 19:19:13.860497216 +0200 | |||
+++ libX11-1.3.1/man/XCreateGC.man 2010-04-12 19:23:16.872621817 +0200 | |||
@@ -151,8 +151,8 @@ XCreateGC, XCopyGC, XChangeGC, XGetGCVal | |||
GC XCreateGC\^(\^Display *\fIdisplay\fP\^, Drawable \fId\fP\^, unsigned long | |||
\fIvaluemask\fP\^, XGCValues *\^\fIvalues\fP\^); | |||
.HP | |||
-int XCopyGC\^(\^Display *\fIdisplay\fP\^, GC \fIsrc\fP\^, GC \fIdest\fP\^, | |||
-unsigned long \fIvaluemask\fP\^); | |||
+int XCopyGC\^(\^Display *\fIdisplay\fP\^, GC \fIsrc\fP\^, | |||
+unsigned long \fIvaluemask\fP\^, GC \fIdest\fP\^); | |||
.HP | |||
int XChangeGC\^(\^Display *\fIdisplay\fP\^, GC \fIgc\fP\^, unsigned long | |||
\fIvaluemask\fP\^, XGCValues *\^\fIvalues\fP\^); |
@@ -0,0 +1,35 @@ | |||
From 956fd30e1046e5779ac0b6c07ec4f0e87250869a Mon Sep 17 00:00:00 2001 | |||
From: Jamey Sharp <jamey@minilop.net> | |||
Date: Wed, 7 Oct 2009 19:31:21 -0700 | |||
Subject: [PATCH] XAllocID must only be called with the Display lock held. | |||
This patch makes XShmAttach follow the same XID allocation pattern used in | |||
other stubs, such as XShmCreatePixmap. | |||
Reported-by: <fdsteve@ihug.co.nz> | |||
Signed-off-by: Jamey Sharp <jamey@minilop.net> | |||
--- | |||
src/XShm.c | 3 +-- | |||
1 files changed, 1 insertions(+), 2 deletions(-) | |||
diff --git a/src/XShm.c b/src/XShm.c | |||
index 922b4cb..38efa9f 100644 | |||
--- a/src/XShm.c | |||
+++ b/src/XShm.c | |||
@@ -235,12 +235,11 @@ Status XShmAttach(Display *dpy, XShmSegmentInfo *shminfo) | |||
ShmCheckExtension (dpy, info, 0); | |||
- shminfo->shmseg = XAllocID(dpy); | |||
LockDisplay(dpy); | |||
GetReq(ShmAttach, req); | |||
req->reqType = info->codes->major_opcode; | |||
req->shmReqType = X_ShmAttach; | |||
- req->shmseg = shminfo->shmseg; | |||
+ req->shmseg = shminfo->shmseg = XAllocID(dpy); | |||
req->shmid = shminfo->shmid; | |||
req->readOnly = shminfo->readOnly ? xTrue : xFalse; | |||
UnlockDisplay(dpy); | |||
-- | |||
1.6.5.2 | |||
@@ -0,0 +1,11 @@ | |||
--- libXt-1.0.2/xt.pc.in.libsm-fix 2006-06-28 14:56:37.000000000 -0400 | |||
+++ libXt-1.0.2/xt.pc.in 2006-06-28 14:56:51.000000000 -0400 | |||
@@ -7,7 +7,7 @@ | |||
Name: Xt | |||
Description: X Toolkit Library | |||
Version: @VERSION@ | |||
-Requires: xproto x11 sm | |||
+Requires: xproto x11 | |||
Requires.private: x11 sm | |||
Cflags: -I${includedir} | |||
Libs: -L${libdir} -lXt |
@@ -0,0 +1,54 @@ | |||
diff -up libdrm-20080814/libdrm/xf86drm.c.no-bc libdrm-20080814/libdrm/xf86drm.c | |||
--- libdrm-20080814/libdrm/xf86drm.c.no-bc 2008-08-14 15:43:09.000000000 +1000 | |||
+++ libdrm-20080814/libdrm/xf86drm.c 2008-08-14 15:45:09.000000000 +1000 | |||
@@ -396,11 +396,6 @@ int drmAvailable(void) | |||
int fd; | |||
if ((fd = drmOpenMinor(0, 1, DRM_NODE_RENDER)) < 0) { | |||
-#ifdef __linux__ | |||
- /* Try proc for backward Linux compatibility */ | |||
- if (!access("/proc/dri/0", R_OK)) | |||
- return 1; | |||
-#endif | |||
return 0; | |||
} | |||
@@ -519,38 +514,6 @@ static int drmOpenByName(const char *nam | |||
} | |||
} | |||
-#ifdef __linux__ | |||
- /* Backward-compatibility /proc support */ | |||
- for (i = 0; i < 8; i++) { | |||
- char proc_name[64], buf[512]; | |||
- char *driver, *pt, *devstring; | |||
- int retcode; | |||
- | |||
- sprintf(proc_name, "/proc/dri/%d/name", i); | |||
- if ((fd = open(proc_name, 0, 0)) >= 0) { | |||
- retcode = read(fd, buf, sizeof(buf)-1); | |||
- close(fd); | |||
- if (retcode) { | |||
- buf[retcode-1] = '\0'; | |||
- for (driver = pt = buf; *pt && *pt != ' '; ++pt) | |||
- ; | |||
- if (*pt) { /* Device is next */ | |||
- *pt = '\0'; | |||
- if (!strcmp(driver, name)) { /* Match */ | |||
- for (devstring = ++pt; *pt && *pt != ' '; ++pt) | |||
- ; | |||
- if (*pt) { /* Found busid */ | |||
- return drmOpenByBusid(++pt); | |||
- } else { /* No busid */ | |||
- return drmOpenDevice(strtol(devstring, NULL, 0),i, DRM_NODE_RENDER); | |||
- } | |||
- } | |||
- } | |||
- } | |||
- } | |||
- } | |||
-#endif | |||
- | |||
return -1; | |||
} | |||
@@ -0,0 +1,12 @@ | |||
diff -up libdrm-20080303/libdrm/xf86drm.h.da libdrm-20080303/libdrm/xf86drm.h | |||
--- libdrm-20080303/libdrm/xf86drm.h.da 2008-03-19 15:26:31.000000000 +1000 | |||
+++ libdrm-20080303/libdrm/xf86drm.h 2008-03-19 15:26:46.000000000 +1000 | |||
@@ -45,7 +45,7 @@ | |||
/* Default /dev/dri directory permissions 0755 */ | |||
#define DRM_DEV_DIRMODE \ | |||
(S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) | |||
-#define DRM_DEV_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) | |||
+#define DRM_DEV_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) | |||
#define DRM_DIR_NAME "/dev/dri" | |||
#define DRM_DEV_NAME "%s/card%d" |
@@ -0,0 +1,295 @@ | |||
diff --git a/libdrm/nouveau/nouveau_bo.c b/libdrm/nouveau/nouveau_bo.c | |||
index b7e6d86..85fc14f 100644 | |||
--- a/libdrm/nouveau/nouveau_bo.c | |||
+++ b/libdrm/nouveau/nouveau_bo.c | |||
@@ -607,6 +607,7 @@ nouveau_bo_emit_buffer(struct nouveau_channel *chan, struct nouveau_bo *bo) | |||
pbbo = nvpb->buffers + nvpb->nr_buffers++; | |||
nvbo->pending = pbbo; | |||
nvbo->pending_channel = chan; | |||
+ nvbo->pending_refcnt = 0; | |||
nouveau_bo_ref(bo, &ref); | |||
pbbo->user_priv = (uint64_t)(unsigned long)ref; | |||
diff --git a/libdrm/nouveau/nouveau_private.h b/libdrm/nouveau/nouveau_private.h | |||
index 9ce87fb..784afc9 100644 | |||
--- a/libdrm/nouveau/nouveau_private.h | |||
+++ b/libdrm/nouveau/nouveau_private.h | |||
@@ -52,6 +52,9 @@ struct nouveau_pushbuf_priv { | |||
unsigned *pushbuf; | |||
unsigned size; | |||
+ unsigned marker; | |||
+ unsigned marker_relocs; | |||
+ | |||
struct drm_nouveau_gem_pushbuf_bo *buffers; | |||
unsigned nr_buffers; | |||
struct drm_nouveau_gem_pushbuf_reloc *relocs; | |||
@@ -99,6 +102,7 @@ struct nouveau_bo_priv { | |||
/* Tracking */ | |||
struct drm_nouveau_gem_pushbuf_bo *pending; | |||
struct nouveau_channel *pending_channel; | |||
+ int pending_refcnt; | |||
int write_marker; | |||
/* Userspace object */ | |||
diff --git a/libdrm/nouveau/nouveau_pushbuf.c b/libdrm/nouveau/nouveau_pushbuf.c | |||
index d434a5f..90250c0 100644 | |||
--- a/libdrm/nouveau/nouveau_pushbuf.c | |||
+++ b/libdrm/nouveau/nouveau_pushbuf.c | |||
@@ -60,17 +60,17 @@ nouveau_pushbuf_emit_reloc(struct nouveau_channel *chan, void *ptr, | |||
uint32_t flags, uint32_t vor, uint32_t tor) | |||
{ | |||
struct nouveau_pushbuf_priv *nvpb = nouveau_pushbuf(chan->pushbuf); | |||
+ struct nouveau_bo_priv *nvbo = nouveau_bo(bo); | |||
struct drm_nouveau_gem_pushbuf_reloc *r; | |||
struct drm_nouveau_gem_pushbuf_bo *pbbo; | |||
uint32_t domains = 0; | |||
if (nvpb->nr_relocs >= NOUVEAU_GEM_MAX_RELOCS) { | |||
fprintf(stderr, "too many relocs!!\n"); | |||
- assert(0); | |||
return -ENOMEM; | |||
} | |||
- if (nouveau_bo(bo)->user && (flags & NOUVEAU_BO_WR)) { | |||
+ if (nvbo->user && (flags & NOUVEAU_BO_WR)) { | |||
fprintf(stderr, "write to user buffer!!\n"); | |||
return -EINVAL; | |||
} | |||
@@ -78,16 +78,21 @@ nouveau_pushbuf_emit_reloc(struct nouveau_channel *chan, void *ptr, | |||
pbbo = nouveau_bo_emit_buffer(chan, bo); | |||
if (!pbbo) { | |||
fprintf(stderr, "buffer emit fail :(\n"); | |||
- assert(0); | |||
return -ENOMEM; | |||
} | |||
+ nvbo->pending_refcnt++; | |||
+ | |||
if (flags & NOUVEAU_BO_VRAM) | |||
domains |= NOUVEAU_GEM_DOMAIN_VRAM; | |||
if (flags & NOUVEAU_BO_GART) | |||
domains |= NOUVEAU_GEM_DOMAIN_GART; | |||
+ | |||
+ if (!(pbbo->valid_domains & domains)) { | |||
+ fprintf(stderr, "no valid domains remain!\n"); | |||
+ return -EINVAL; | |||
+ } | |||
pbbo->valid_domains &= domains; | |||
- assert(pbbo->valid_domains); | |||
assert(flags & NOUVEAU_BO_RDWR); | |||
if (flags & NOUVEAU_BO_RD) { | |||
@@ -95,7 +100,7 @@ nouveau_pushbuf_emit_reloc(struct nouveau_channel *chan, void *ptr, | |||
} | |||
if (flags & NOUVEAU_BO_WR) { | |||
pbbo->write_domains |= domains; | |||
- nouveau_bo(bo)->write_marker = 1; | |||
+ nvbo->write_marker = 1; | |||
} | |||
r = nvpb->relocs + nvpb->nr_relocs++; | |||
@@ -322,18 +327,25 @@ restart_push: | |||
/* Update presumed offset/domain for any buffers that moved. | |||
* Dereference all buffers on validate list | |||
*/ | |||
- for (i = 0; i < nvpb->nr_buffers; i++) { | |||
- struct drm_nouveau_gem_pushbuf_bo *pbbo = &nvpb->buffers[i]; | |||
+ for (i = 0; i < nvpb->nr_relocs; i++) { | |||
+ struct drm_nouveau_gem_pushbuf_reloc *r = &nvpb->relocs[i]; | |||
+ struct drm_nouveau_gem_pushbuf_bo *pbbo = | |||
+ &nvpb->buffers[r->bo_index]; | |||
struct nouveau_bo *bo = (void *)(unsigned long)pbbo->user_priv; | |||
+ struct nouveau_bo_priv *nvbo = nouveau_bo(bo); | |||
+ | |||
+ if (--nvbo->pending_refcnt) | |||
+ continue; | |||
if (pbbo->presumed_ok == 0) { | |||
- nouveau_bo(bo)->domain = pbbo->presumed_domain; | |||
- nouveau_bo(bo)->offset = pbbo->presumed_offset; | |||
+ nvbo->domain = pbbo->presumed_domain; | |||
+ nvbo->offset = pbbo->presumed_offset; | |||
} | |||
- nouveau_bo(bo)->pending = NULL; | |||
+ nvbo->pending = NULL; | |||
nouveau_bo_ref(NULL, &bo); | |||
} | |||
+ | |||
nvpb->nr_buffers = 0; | |||
nvpb->nr_relocs = 0; | |||
@@ -343,6 +355,57 @@ restart_push: | |||
if (chan->flush_notify) | |||
chan->flush_notify(chan); | |||
+ nvpb->marker = 0; | |||
return ret; | |||
} | |||
+int | |||
+nouveau_pushbuf_marker_emit(struct nouveau_channel *chan, | |||
+ unsigned wait_dwords, unsigned wait_relocs) | |||
+{ | |||
+ struct nouveau_pushbuf_priv *nvpb = nouveau_pushbuf(chan->pushbuf); | |||
+ | |||
+ if (AVAIL_RING(chan) < wait_dwords) | |||
+ return nouveau_pushbuf_flush(chan, wait_dwords); | |||
+ | |||
+ if (nvpb->nr_relocs + wait_relocs >= NOUVEAU_GEM_MAX_RELOCS) | |||
+ return nouveau_pushbuf_flush(chan, wait_dwords); | |||
+ | |||
+ nvpb->marker = nvpb->base.cur - nvpb->pushbuf; | |||
+ nvpb->marker_relocs = nvpb->nr_relocs; | |||
+ return 0; | |||
+} | |||
+ | |||
+void | |||
+nouveau_pushbuf_marker_undo(struct nouveau_channel *chan) | |||
+{ | |||
+ struct nouveau_pushbuf_priv *nvpb = nouveau_pushbuf(chan->pushbuf); | |||
+ unsigned i; | |||
+ | |||
+ if (!nvpb->marker) | |||
+ return; | |||
+ | |||
+ /* undo any relocs/buffers added to the list since last marker */ | |||
+ for (i = nvpb->marker_relocs; i < nvpb->nr_relocs; i++) { | |||
+ struct drm_nouveau_gem_pushbuf_reloc *r = &nvpb->relocs[i]; | |||
+ struct drm_nouveau_gem_pushbuf_bo *pbbo = | |||
+ &nvpb->buffers[r->bo_index]; | |||
+ struct nouveau_bo *bo = (void *)(unsigned long)pbbo->user_priv; | |||
+ struct nouveau_bo_priv *nvbo = nouveau_bo(bo); | |||
+ | |||
+ if (--nvbo->pending_refcnt) | |||
+ continue; | |||
+ | |||
+ nvbo->pending = NULL; | |||
+ nouveau_bo_ref(NULL, &bo); | |||
+ nvpb->nr_buffers--; | |||
+ } | |||
+ nvpb->nr_relocs = nvpb->marker_relocs; | |||
+ | |||
+ /* reset pushbuf back to last marker */ | |||
+ nvpb->base.cur = nvpb->pushbuf + nvpb->marker; | |||
+ nvpb->base.remaining = nvpb->size - nvpb->marker; | |||
+ nvpb->marker = 0; | |||
+} | |||
+ | |||
+ | |||
diff --git a/libdrm/nouveau/nouveau_pushbuf.h b/libdrm/nouveau/nouveau_pushbuf.h | |||
index 3c746ed..c7ac8c4 100644 | |||
--- a/libdrm/nouveau/nouveau_pushbuf.h | |||
+++ b/libdrm/nouveau/nouveau_pushbuf.h | |||
@@ -40,11 +40,30 @@ int | |||
nouveau_pushbuf_flush(struct nouveau_channel *, unsigned min); | |||
int | |||
+nouveau_pushbuf_marker_emit(struct nouveau_channel *chan, | |||
+ unsigned wait_dwords, unsigned wait_relocs); | |||
+ | |||
+void | |||
+nouveau_pushbuf_marker_undo(struct nouveau_channel *chan); | |||
+ | |||
+int | |||
nouveau_pushbuf_emit_reloc(struct nouveau_channel *, void *ptr, | |||
struct nouveau_bo *, uint32_t data, uint32_t data2, | |||
uint32_t flags, uint32_t vor, uint32_t tor); | |||
/* Push buffer access macros */ | |||
+static __inline__ int | |||
+MARK_RING(struct nouveau_channel *chan, unsigned dwords, unsigned relocs) | |||
+{ | |||
+ return nouveau_pushbuf_marker_emit(chan, dwords, relocs); | |||
+} | |||
+ | |||
+static __inline__ void | |||
+MARK_UNDO(struct nouveau_channel *chan) | |||
+{ | |||
+ nouveau_pushbuf_marker_undo(chan); | |||
+} | |||
+ | |||
static __inline__ void | |||
OUT_RING(struct nouveau_channel *chan, unsigned data) | |||
{ | |||
@@ -116,62 +135,62 @@ BIND_RING(struct nouveau_channel *chan, struct nouveau_grobj *gr, unsigned sc) | |||
OUT_RING (chan, gr->handle); | |||
} | |||
-static __inline__ void | |||
+static __inline__ int | |||
OUT_RELOC(struct nouveau_channel *chan, struct nouveau_bo *bo, | |||
unsigned data, unsigned flags, unsigned vor, unsigned tor) | |||
{ | |||
- nouveau_pushbuf_emit_reloc(chan, chan->pushbuf->cur++, bo, | |||
- data, 0, flags, vor, tor); | |||
+ return nouveau_pushbuf_emit_reloc(chan, chan->pushbuf->cur++, bo, | |||
+ data, 0, flags, vor, tor); | |||
} | |||
-static __inline__ void | |||
+static __inline__ int | |||
OUT_RELOC2(struct nouveau_channel *chan, struct nouveau_bo *bo, | |||
unsigned data, unsigned data2, unsigned flags, | |||
unsigned vor, unsigned tor) | |||
{ | |||
- nouveau_pushbuf_emit_reloc(chan, chan->pushbuf->cur++, bo, | |||
- data, data2, flags, vor, tor); | |||
+ return nouveau_pushbuf_emit_reloc(chan, chan->pushbuf->cur++, bo, | |||
+ data, data2, flags, vor, tor); | |||
} | |||
/* Raw data + flags depending on FB/TT buffer */ | |||
-static __inline__ void | |||
+static __inline__ int | |||
OUT_RELOCd(struct nouveau_channel *chan, struct nouveau_bo *bo, | |||
unsigned data, unsigned flags, unsigned vor, unsigned tor) | |||
{ | |||
- OUT_RELOC(chan, bo, data, flags | NOUVEAU_BO_OR, vor, tor); | |||
+ return OUT_RELOC(chan, bo, data, flags | NOUVEAU_BO_OR, vor, tor); | |||
} | |||
/* FB/TT object handle */ | |||
-static __inline__ void | |||
+static __inline__ int | |||
OUT_RELOCo(struct nouveau_channel *chan, struct nouveau_bo *bo, | |||
unsigned flags) | |||
{ | |||
- OUT_RELOC(chan, bo, 0, flags | NOUVEAU_BO_OR, | |||
- chan->vram->handle, chan->gart->handle); | |||
+ return OUT_RELOC(chan, bo, 0, flags | NOUVEAU_BO_OR, | |||
+ chan->vram->handle, chan->gart->handle); | |||
} | |||
/* Low 32-bits of offset */ | |||
-static __inline__ void | |||
+static __inline__ int | |||
OUT_RELOCl(struct nouveau_channel *chan, struct nouveau_bo *bo, | |||
unsigned delta, unsigned flags) | |||
{ | |||
- OUT_RELOC(chan, bo, delta, flags | NOUVEAU_BO_LOW, 0, 0); | |||
+ return OUT_RELOC(chan, bo, delta, flags | NOUVEAU_BO_LOW, 0, 0); | |||
} | |||
/* Low 32-bits of offset + GPU linear access range info */ | |||
-static __inline__ void | |||
+static __inline__ int | |||
OUT_RELOCr(struct nouveau_channel *chan, struct nouveau_bo *bo, | |||
unsigned delta, unsigned size, unsigned flags) | |||
{ | |||
- OUT_RELOC2(chan, bo, delta, size, flags | NOUVEAU_BO_LOW, 0, 0); | |||
+ return OUT_RELOC2(chan, bo, delta, size, flags | NOUVEAU_BO_LOW, 0, 0); | |||
} | |||
/* High 32-bits of offset */ | |||
-static __inline__ void | |||
+static __inline__ int | |||
OUT_RELOCh(struct nouveau_channel *chan, struct nouveau_bo *bo, | |||
unsigned delta, unsigned flags) | |||
{ | |||
- OUT_RELOC(chan, bo, delta, flags | NOUVEAU_BO_HIGH, 0, 0); | |||
+ return OUT_RELOC(chan, bo, delta, flags | NOUVEAU_BO_HIGH, 0, 0); | |||
} | |||
#endif |
@@ -0,0 +1,103 @@ | |||
diff --git a/libdrm/nouveau/nouveau_private.h b/libdrm/nouveau/nouveau_private.h | |||
index 67144e3..9ce87fb 100644 | |||
--- a/libdrm/nouveau/nouveau_private.h | |||
+++ b/libdrm/nouveau/nouveau_private.h | |||
@@ -41,6 +41,7 @@ | |||
struct nouveau_pushbuf_priv { | |||
struct nouveau_pushbuf base; | |||
+ int no_aper_update; | |||
int use_cal; | |||
uint32_t cal_suffix0; | |||
uint32_t cal_suffix1; | |||
diff --git a/libdrm/nouveau/nouveau_pushbuf.c b/libdrm/nouveau/nouveau_pushbuf.c | |||
index fbcddd7..d434a5f 100644 | |||
--- a/libdrm/nouveau/nouveau_pushbuf.c | |||
+++ b/libdrm/nouveau/nouveau_pushbuf.c | |||
@@ -202,10 +202,17 @@ nouveau_pushbuf_init_call(struct nouveau_channel *chan) | |||
req.channel = chan->id; | |||
req.handle = 0; | |||
ret = drmCommandWriteRead(nouveau_device(dev)->fd, | |||
- DRM_NOUVEAU_GEM_PUSHBUF_CALL, | |||
+ DRM_NOUVEAU_GEM_PUSHBUF_CALL2, | |||
&req, sizeof(req)); | |||
- if (ret) | |||
- return; | |||
+ if (ret) { | |||
+ ret = drmCommandWriteRead(nouveau_device(dev)->fd, | |||
+ DRM_NOUVEAU_GEM_PUSHBUF_CALL2, | |||
+ &req, sizeof(req)); | |||
+ if (ret) | |||
+ return; | |||
+ | |||
+ nvpb->no_aper_update = 1; | |||
+ } | |||
for (i = 0; i < CALPB_BUFFERS; i++) { | |||
ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, | |||
@@ -282,14 +289,18 @@ restart_cal: | |||
nvpb->current_offset; | |||
req.suffix0 = nvpb->cal_suffix0; | |||
req.suffix1 = nvpb->cal_suffix1; | |||
- ret = drmCommandWriteRead(nvdev->fd, | |||
- DRM_NOUVEAU_GEM_PUSHBUF_CALL, | |||
+ ret = drmCommandWriteRead(nvdev->fd, nvpb->no_aper_update ? | |||
+ DRM_NOUVEAU_GEM_PUSHBUF_CALL : | |||
+ DRM_NOUVEAU_GEM_PUSHBUF_CALL2, | |||
&req, sizeof(req)); | |||
if (ret == -EAGAIN) | |||
goto restart_cal; | |||
nvpb->cal_suffix0 = req.suffix0; | |||
nvpb->cal_suffix1 = req.suffix1; | |||
- assert(ret == 0); | |||
+ if (!nvpb->no_aper_update) { | |||
+ nvdev->base.vm_vram_size = req.vram_available; | |||
+ nvdev->base.vm_gart_size = req.gart_available; | |||
+ } | |||
} else { | |||
struct drm_nouveau_gem_pushbuf req; | |||
@@ -305,7 +316,6 @@ restart_push: | |||
&req, sizeof(req)); | |||
if (ret == -EAGAIN) | |||
goto restart_push; | |||
- assert(ret == 0); | |||
} | |||
@@ -328,12 +338,11 @@ restart_push: | |||
nvpb->nr_relocs = 0; | |||
/* Allocate space for next push buffer */ | |||
- ret = nouveau_pushbuf_space(chan, min); | |||
- assert(!ret); | |||
+ assert(!nouveau_pushbuf_space(chan, min)); | |||
if (chan->flush_notify) | |||
chan->flush_notify(chan); | |||
- return 0; | |||
+ return ret; | |||
} | |||
diff --git a/shared-core/nouveau_drm.h b/shared-core/nouveau_drm.h | |||
index 2050357..1e67c44 100644 | |||
--- a/shared-core/nouveau_drm.h | |||
+++ b/shared-core/nouveau_drm.h | |||
@@ -155,6 +155,9 @@ struct drm_nouveau_gem_pushbuf_call { | |||
uint64_t relocs; | |||
uint32_t suffix0; | |||
uint32_t suffix1; | |||
+ /* below only accessed for CALL2 */ | |||
+ uint64_t vram_available; | |||
+ uint64_t gart_available; | |||
}; | |||
struct drm_nouveau_gem_pin { | |||
@@ -212,5 +215,6 @@ struct drm_nouveau_sarea { | |||
#define DRM_NOUVEAU_GEM_CPU_PREP 0x45 | |||
#define DRM_NOUVEAU_GEM_CPU_FINI 0x46 | |||
#define DRM_NOUVEAU_GEM_INFO 0x47 | |||
+#define DRM_NOUVEAU_GEM_PUSHBUF_CALL2 0x48 | |||
#endif /* __NOUVEAU_DRM_H__ */ |
@@ -0,0 +1,50 @@ | |||
From 67628aa39dd74807989492af5451a3a5c0232e39 Mon Sep 17 00:00:00 2001 | |||
From: Ben Skeggs <bskeggs@redhat.com> | |||
Date: Tue, 20 Oct 2009 12:57:46 +1000 | |||
Subject: [PATCH] nouveau: retry if pushbuf ioctl interrupted by signal | |||
Signed-off-by: Ben Skeggs <bskeggs@redhat.com> | |||
--- | |||
libdrm/nouveau/nouveau_pushbuf.c | 6 ++++++ | |||
1 files changed, 6 insertions(+), 0 deletions(-) | |||
diff --git a/libdrm/nouveau/nouveau_pushbuf.c b/libdrm/nouveau/nouveau_pushbuf.c | |||
index 1192e22..fbcddd7 100644 | |||
--- a/libdrm/nouveau/nouveau_pushbuf.c | |||
+++ b/libdrm/nouveau/nouveau_pushbuf.c | |||
@@ -270,6 +270,7 @@ nouveau_pushbuf_flush(struct nouveau_channel *chan, unsigned min) | |||
if (nvpb->base.remaining > 2) /* space() will fixup if not */ | |||
nvpb->base.remaining -= 2; | |||
+restart_cal: | |||
req.channel = chan->id; | |||
req.handle = nvpb->buffer[nvpb->current]->handle; | |||
req.offset = nvpb->current_offset * 4; | |||
@@ -284,12 +285,15 @@ nouveau_pushbuf_flush(struct nouveau_channel *chan, unsigned min) | |||
ret = drmCommandWriteRead(nvdev->fd, | |||
DRM_NOUVEAU_GEM_PUSHBUF_CALL, | |||
&req, sizeof(req)); | |||
+ if (ret == -EAGAIN) | |||
+ goto restart_cal; | |||
nvpb->cal_suffix0 = req.suffix0; | |||
nvpb->cal_suffix1 = req.suffix1; | |||
assert(ret == 0); | |||
} else { | |||
struct drm_nouveau_gem_pushbuf req; | |||
+restart_push: | |||
req.channel = chan->id; | |||
req.nr_dwords = nvpb->size - nvpb->base.remaining; | |||
req.dwords = (uint64_t)(unsigned long)nvpb->pushbuf; | |||
@@ -299,6 +303,8 @@ nouveau_pushbuf_flush(struct nouveau_channel *chan, unsigned min) | |||
req.relocs = (uint64_t)(unsigned long)nvpb->relocs; | |||
ret = drmCommandWrite(nvdev->fd, DRM_NOUVEAU_GEM_PUSHBUF, | |||
&req, sizeof(req)); | |||
+ if (ret == -EAGAIN) | |||
+ goto restart_push; | |||
assert(ret == 0); | |||
} | |||
-- | |||
1.6.5.1 | |||
@@ -0,0 +1,174 @@ | |||
diff --git a/libdrm/xf86drm.h b/libdrm/xf86drm.h | |||
index c1d173c..67bea37 100644 | |||
--- a/libdrm/xf86drm.h | |||
+++ b/libdrm/xf86drm.h | |||
@@ -667,4 +667,22 @@ extern void drmMsg(const char *format, ...); | |||
extern int drmSetMaster(int fd); | |||
extern int drmDropMaster(int fd); | |||
+#define DRM_EVENT_CONTEXT_VERSION 1 | |||
+ | |||
+typedef struct _drmEventContext { | |||
+ | |||
+ /* This struct is versioned so we can add more pointers if we | |||
+ * add more events. */ | |||
+ int version; | |||
+ | |||
+ void (*page_flip_handler)(int fd, | |||
+ unsigned int frame, | |||
+ unsigned int tv_sec, | |||
+ unsigned int tv_usec, | |||
+ void *user_data); | |||
+ | |||
+} drmEventContext, *drmEventContextPtr; | |||
+ | |||
+extern int drmHandleEvent(int fd, drmEventContextPtr evctx); | |||
+ | |||
#endif | |||
diff --git a/libdrm/xf86drmMode.c b/libdrm/xf86drmMode.c | |||
index ea11207..f601a00 100644 | |||
--- a/libdrm/xf86drmMode.c | |||
+++ b/libdrm/xf86drmMode.c | |||
@@ -664,3 +664,56 @@ int drmModeCrtcSetGamma(int fd, uint32_t crtc_id, uint32_t size, | |||
return 0; | |||
} | |||
+ | |||
+int drmModePageFlip(int fd, uint32_t crtc_id, uint32_t fb_id, void *user_data) | |||
+{ | |||
+ struct drm_mode_page_flip flip; | |||
+ | |||
+ flip.fb_id = fb_id; | |||
+ flip.crtc_id = crtc_id; | |||
+ flip.user_data = VOID2U64(user_data); | |||
+ flip.flags = 0; | |||
+ | |||
+ return drmIoctl(fd, DRM_IOCTL_MODE_PAGE_FLIP, &flip); | |||
+} | |||
+ | |||
+int drmHandleEvent(int fd, drmEventContextPtr evctx) | |||
+{ | |||
+ char buffer[1024]; | |||
+ int len, i; | |||
+ struct drm_event *e; | |||
+ struct drm_event_page_flip *page_flip; | |||
+ | |||
+ /* The DRM read semantics guarantees that we always get only | |||
+ * complete events. */ | |||
+ | |||
+ len = read(fd, buffer, sizeof buffer); | |||
+ if (len == 0) | |||
+ return 0; | |||
+ if (len < sizeof *e) | |||
+ return -1; | |||
+ | |||
+ i = 0; | |||
+ while (i < len) { | |||
+ e = (struct drm_event *) &buffer[i]; | |||
+ switch (e->type) { | |||
+ case DRM_EVENT_MODE_PAGE_FLIP: | |||
+ if (evctx->version < 1 || | |||
+ evctx->page_flip_handler == NULL) | |||
+ break; | |||
+ page_flip = (struct drm_event_page_flip *) e; | |||
+ evctx->page_flip_handler(fd, | |||
+ page_flip->frame, | |||
+ page_flip->tv_sec, | |||
+ page_flip->tv_usec, | |||
+ U642VOID (page_flip->user_data)); | |||
+ break; | |||
+ | |||
+ default: | |||
+ break; | |||
+ } | |||
+ i += e->length; | |||
+ } | |||
+ | |||
+ return 0; | |||
+} | |||
diff --git a/libdrm/xf86drmMode.h b/libdrm/xf86drmMode.h | |||
index 62304bb..fe64707 100644 | |||
--- a/libdrm/xf86drmMode.h | |||
+++ b/libdrm/xf86drmMode.h | |||
@@ -259,8 +259,6 @@ typedef struct _drmModeConnector { | |||
uint32_t *encoders; /**< List of encoder ids */ | |||
} drmModeConnector, *drmModeConnectorPtr; | |||
- | |||
- | |||
extern void drmModeFreeModeInfo( drmModeModeInfoPtr ptr ); | |||
extern void drmModeFreeResources( drmModeResPtr ptr ); | |||
extern void drmModeFreeFB( drmModeFBPtr ptr ); | |||
@@ -362,3 +360,4 @@ extern int drmModeCrtcSetGamma(int fd, uint32_t crtc_id, uint32_t size, | |||
uint16_t *red, uint16_t *green, uint16_t *blue); | |||
extern int drmModeCrtcGetGamma(int fd, uint32_t crtc_id, uint32_t size, | |||
uint16_t *red, uint16_t *green, uint16_t *blue); | |||
+extern int drmModePageFlip(int fd, uint32_t crtc_id, uint32_t fb_id, void *user_data); | |||
diff --git a/shared-core/drm.h b/shared-core/drm.h | |||
index 97fab9a..8b504cb 100644 | |||
--- a/shared-core/drm.h | |||
+++ b/shared-core/drm.h | |||
@@ -1113,6 +1113,7 @@ struct drm_gem_open { | |||
#define DRM_IOCTL_MODE_GETFB DRM_IOWR(0xAD, struct drm_mode_fb_cmd) | |||
#define DRM_IOCTL_MODE_ADDFB DRM_IOWR(0xAE, struct drm_mode_fb_cmd) | |||
#define DRM_IOCTL_MODE_RMFB DRM_IOWR(0xAF, uint32_t) | |||
+#define DRM_IOCTL_MODE_PAGE_FLIP DRM_IOW( 0xB0, struct drm_mode_page_flip) | |||
/*@}*/ | |||
@@ -1128,6 +1129,30 @@ struct drm_gem_open { | |||
#define DRM_COMMAND_BASE 0x40 | |||
#define DRM_COMMAND_END 0xA0 | |||
+/** | |||
+ * Header for events written back to userspace on the drm fd. The | |||
+ * type defines the type of event, the length specifies the total | |||
+ * length of the event (including the header), and user_data is | |||
+ * typically a 64 bit value passed with the ioctl that triggered the | |||
+ * event. A read on the drm fd will always only return complete | |||
+ * events, that is, if for example the read buffer is 100 bytes, and | |||
+ * there are two 64 byte events pending, only one will be returned. | |||
+ */ | |||
+struct drm_event { | |||
+ uint32_t type; | |||
+ uint32_t length; | |||
+}; | |||
+ | |||
+#define DRM_EVENT_MODE_PAGE_FLIP 0x01 | |||
+ | |||
+struct drm_event_page_flip { | |||
+ struct drm_event base; | |||
+ uint64_t user_data; | |||
+ uint32_t tv_sec; | |||
+ uint32_t tv_usec; | |||
+ uint32_t frame; | |||
+}; | |||
+ | |||
/* typedef area */ | |||
#ifndef __KERNEL__ | |||
typedef struct drm_clip_rect drm_clip_rect_t; | |||
diff --git a/shared-core/drm_mode.h b/shared-core/drm_mode.h | |||
index 9b92733..bebe4e7 100644 | |||
--- a/shared-core/drm_mode.h | |||
+++ b/shared-core/drm_mode.h | |||
@@ -270,4 +270,20 @@ struct drm_mode_crtc_lut { | |||
uint64_t blue; | |||
}; | |||
+#define DRM_MODE_PAGE_FLIP_WAIT (1<<0) /* block on previous page flip */ | |||
+#define DRM_MODE_PAGE_FLIP_FLAGS_MASK (DRM_MODE_PAGE_FLIP_WAIT) | |||
+ | |||
+struct drm_mode_page_flip { | |||
+ /** Handle of new front buffer */ | |||
+ uint32_t fb_id; | |||
+ uint32_t crtc_id; | |||
+ | |||
+ /* 64 bit cookie returned to userspace in the page flip event. */ | |||
+ uint64_t user_data; | |||
+ /** | |||
+ * page flip flags (wait on flip only for now) | |||
+ */ | |||
+ uint32_t flags; | |||
+}; | |||
+ | |||
#endif |
@@ -0,0 +1,13 @@ | |||
diff --git ./configure.ac ./configure.ac | |||
index fc28ef9..63ef0c8 100644 | |||
--- ./configure.ac | |||
+++ ./configure.ac | |||
@@ -37,7 +37,7 @@ AC_PROG_CC | |||
AC_PROG_LIBTOOL | |||
XORG_CWARNFLAGS | |||
-encodingsdir=${libdir}/X11/fonts/encodings | |||
+encodingsdir=$(pkg-config --variable=fontdir fontutil)/encodings | |||
AC_ARG_WITH(encodingsdir, AC_HELP_STRING([--with-encodingsdir=<pathname>], | |||
[Path to font encodings]), [encodingsdir="$withval"]) | |||
ENCODINGSDIR="$encodingsdir" |
@@ -0,0 +1,15 @@ | |||
diff -up Mesa-7.1/src/mesa/drivers/dri/intel/intel_fbo.c.intel-glthread Mesa-7.1/src/mesa/drivers/dri/intel/intel_fbo.c | |||
--- Mesa-7.1/src/mesa/drivers/dri/intel/intel_fbo.c.intel-glthread 2008-08-25 10:49:40.000000000 -0400 | |||
+++ Mesa-7.1/src/mesa/drivers/dri/intel/intel_fbo.c 2008-08-28 14:26:17.000000000 -0400 | |||
@@ -633,11 +633,6 @@ intel_render_texture(GLcontext * ctx, | |||
return; | |||
} | |||
- DBG("Begin render texture tid %x tex=%u w=%d h=%d refcount=%d\n", | |||
- _glthread_GetID(), | |||
- att->Texture->Name, newImage->Width, newImage->Height, | |||
- irb->Base.RefCount); | |||
- | |||
/* point the renderbufer's region to the texture image region */ | |||
intel_image = intel_texture_image(newImage); | |||
if (irb->region != intel_image->mt->region) { |
@@ -0,0 +1,12 @@ | |||
diff -up Mesa-7.1/src/mesa/drivers/osmesa/Makefile.jx Mesa-7.1/src/mesa/drivers/osmesa/Makefile | |||
--- Mesa-7.1/src/mesa/drivers/osmesa/Makefile.jx 2008-08-28 14:05:47.000000000 -0400 | |||
+++ Mesa-7.1/src/mesa/drivers/osmesa/Makefile 2008-08-28 14:07:13.000000000 -0400 | |||
@@ -46,7 +46,7 @@ osmesa8: $(TOP)/lib/$(OSMESA_LIB_NAME) | |||
$(TOP)/lib/$(OSMESA_LIB_NAME): $(OBJECTS) | |||
$(MKLIB) -o $(OSMESA_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \ | |||
- -major $(MESA_MAJOR) -minor $(MESA_MINOR) -patch $(MESA_TINY) \ | |||
+ -major 6 -minor 5 -patch 3 \ | |||
-install $(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) \ | |||
-id $(INSTALL_LIB_DIR)/lib$(OSMESA_LIB).$(MESA_MAJOR).dylib \ | |||
$(OSMESA_LIB_DEPS) $(OBJECTS) |
@@ -0,0 +1,28 @@ | |||
diff -up mesa-20091030/src/glx/x11/glx_pbuffer.c.jx mesa-20091030/src/glx/x11/glx_pbuffer.c | |||
--- mesa-20091030/src/glx/x11/glx_pbuffer.c.jx 2009-10-29 21:12:50.000000000 -0400 | |||
+++ mesa-20091030/src/glx/x11/glx_pbuffer.c 2009-11-17 14:56:07.000000000 -0500 | |||
@@ -35,6 +35,8 @@ | |||
#include <X11/extensions/Xext.h> | |||
#include <assert.h> | |||
#include <string.h> | |||
+#include <unistd.h> | |||
+#include <limits.h> | |||
#include "glapi.h" | |||
#include "glxextensions.h" | |||
#include "glcontextmodes.h" | |||
@@ -56,10 +58,13 @@ warn_GLX_1_3(Display *dpy, const char *f | |||
__GLXdisplayPrivate *priv = __glXInitialize(dpy); | |||
if (priv->minorVersion < 3) { | |||
+ char buf[PATH_MAX]; | |||
+ if (readlink("/proc/self/exe", buf, PATH_MAX) == -1) | |||
+ buf[0] = '\0'; | |||
fprintf(stderr, | |||
- "WARNING: Application calling GLX 1.3 function \"%s\" " | |||
+ "WARNING: Application %s calling GLX 1.3 function \"%s\" " | |||
"when GLX 1.3 is not supported! This is an application bug!\n", | |||
- function_name); | |||
+ buf, function_name); | |||
} | |||
} | |||
@@ -0,0 +1,12 @@ | |||
diff -up mesa-20090813/src/mesa/drivers/dri/common/vblank.c.jx mesa-20090813/src/mesa/drivers/dri/common/vblank.c | |||
--- mesa-20090813/src/mesa/drivers/dri/common/vblank.c.jx 2009-08-13 09:28:01.000000000 -0400 | |||
+++ mesa-20090813/src/mesa/drivers/dri/common/vblank.c 2009-09-08 14:07:51.000000000 -0400 | |||
@@ -256,7 +256,7 @@ static int do_wait( drmVBlank * vbl, GLu | |||
if ( ret != 0 ) { | |||
static GLboolean first_time = GL_TRUE; | |||
- if ( first_time ) { | |||
+ if (0) { | |||
fprintf(stderr, | |||
"%s: drmWaitVBlank returned %d, IRQs don't seem to be" | |||
" working correctly.\nTry adjusting the vblank_mode" |
@@ -0,0 +1,46 @@ | |||
diff -up mesa-20091030/configure.ac.da mesa-20091030/configure.ac | |||
--- mesa-20091030/configure.ac.da 2009-10-30 11:12:50.000000000 +1000 | |||
+++ mesa-20091030/configure.ac 2009-10-30 14:53:02.000000000 +1000 | |||
@@ -716,7 +716,7 @@ if test "$mesa_driver" = dri; then | |||
# because there is no x86-64 system where they could *ever* | |||
# be used. | |||
if test "x$DRI_DIRS" = "xyes"; then | |||
- DRI_DIRS="i915 i965 mach64 mga r128 r200 r300 r600 radeon \ | |||
+ DRI_DIRS="i915 i965 mga r128 r200 r300 r600 radeon \ | |||
savage tdfx unichrome swrast" | |||
fi | |||
;; | |||
@@ -724,13 +724,13 @@ if test "$mesa_driver" = dri; then | |||
# Build only the drivers for cards that exist on PowerPC. | |||
# At some point MGA will be added, but not yet. | |||
if test "x$DRI_DIRS" = "xyes"; then | |||
- DRI_DIRS="mach64 r128 r200 r300 r600 radeon tdfx swrast" | |||
+ DRI_DIRS="r128 r200 r300 r600 radeon tdfx swrast" | |||
fi | |||
;; | |||
sparc*) | |||
# Build only the drivers for cards that exist on sparc` | |||
if test "x$DRI_DIRS" = "xyes"; then | |||
- DRI_DIRS="mach64 r128 r200 r300 r600 radeon ffb swrast" | |||
+ DRI_DIRS="r128 r200 r300 r600 radeon ffb swrast" | |||
fi | |||
;; | |||
esac | |||
@@ -749,7 +749,7 @@ if test "$mesa_driver" = dri; then | |||
# ffb and gamma are missing because they have not been converted | |||
# to use the new interface. | |||
if test "x$DRI_DIRS" = "xyes"; then | |||
- DRI_DIRS="i810 i915 i965 mach64 mga r128 r200 r300 r600 radeon tdfx \ | |||
+ DRI_DIRS="i810 i915 i965 mga r128 r200 r300 r600 radeon tdfx \ | |||
unichrome savage sis swrast" | |||
fi | |||
;; | |||
@@ -768,7 +768,7 @@ if test "$mesa_driver" = dri; then | |||
# default drivers | |||
if test "x$DRI_DIRS" = "xyes"; then | |||
- DRI_DIRS="i810 i915 i965 mach64 mga r128 r200 r300 r600 radeon \ | |||
+ DRI_DIRS="i810 i915 i965 mga r128 r200 r300 r600 radeon \ | |||
savage sis tdfx unichrome ffb swrast" | |||
fi | |||
@@ -0,0 +1,554 @@ | |||
diff -ur fltk-1.3.2.org/FL/Fl_Image.H fltk-1.3.2/FL/Fl_Image.H | |||
--- fltk-1.3.2.org/FL/Fl_Image.H 2012-11-09 17:02:08.000000000 +0100 | |||
+++ fltk-1.3.2/FL/Fl_Image.H 2013-01-16 14:40:51.543230638 +0100 | |||
@@ -26,6 +26,7 @@ | |||
#include <stdlib.h> | |||
class Fl_Widget; | |||
+class Fl_Pixmap; | |||
struct Fl_Menu_Item; | |||
struct Fl_Label; | |||
@@ -203,6 +204,7 @@ | |||
*/ | |||
Fl_RGB_Image(const uchar *bits, int W, int H, int D=3, int LD=0) : | |||
Fl_Image(W,H,D), array(bits), alloc_array(0), id_(0), mask_(0) {data((const char **)&array, 1); ld(LD);} | |||
+ Fl_RGB_Image(const Fl_Pixmap *pxm, Fl_Color bg=FL_GRAY); | |||
virtual ~Fl_RGB_Image(); | |||
virtual Fl_Image *copy(int W, int H); | |||
Fl_Image *copy() { return copy(w(), h()); } | |||
diff -ur fltk-1.3.2.org/src/fl_draw_pixmap.cxx fltk-1.3.2/src/fl_draw_pixmap.cxx | |||
--- fltk-1.3.2.org/src/fl_draw_pixmap.cxx 2012-04-22 05:09:31.000000000 +0200 | |||
+++ fltk-1.3.2/src/fl_draw_pixmap.cxx 2013-01-16 14:40:51.542230588 +0100 | |||
@@ -58,99 +58,6 @@ | |||
return 1; | |||
} | |||
-#ifdef U64 | |||
- | |||
-// The callback from fl_draw_image to get a row of data passes this: | |||
-struct pixmap_data { | |||
- int w, h; | |||
- const uchar*const* data; | |||
- union { | |||
- U64 colors[256]; | |||
- U64* byte1[256]; | |||
- }; | |||
-}; | |||
- | |||
-// callback for 1 byte per pixel: | |||
-static void cb1(void*v, int x, int y, int w, uchar* buf) { | |||
- pixmap_data& d = *(pixmap_data*)v; | |||
- const uchar* p = d.data[y]+x; | |||
- U64* q = (U64*)buf; | |||
- for (int X=w; X>0; X-=2, p += 2) { | |||
- if (X>1) { | |||
-# if WORDS_BIGENDIAN | |||
- *q++ = (d.colors[p[0]]<<32) | d.colors[p[1]]; | |||
-# else | |||
- *q++ = (d.colors[p[1]]<<32) | d.colors[p[0]]; | |||
-# endif | |||
- } else { | |||
-# if WORDS_BIGENDIAN | |||
- *q++ = d.colors[p[0]]<<32; | |||
-# else | |||
- *q++ = d.colors[p[0]]; | |||
-# endif | |||
- } | |||
- } | |||
-} | |||
- | |||
-// callback for 2 bytes per pixel: | |||
-static void cb2(void*v, int x, int y, int w, uchar* buf) { | |||
- pixmap_data& d = *(pixmap_data*)v; | |||
- const uchar* p = d.data[y]+2*x; | |||
- U64* q = (U64*)buf; | |||
- for (int X=w; X>0; X-=2) { | |||
- U64* colors = d.byte1[*p++]; | |||
- int index = *p++; | |||
- if (X>1) { | |||
- U64* colors1 = d.byte1[*p++]; | |||
- int index1 = *p++; | |||
-# if WORDS_BIGENDIAN | |||
- *q++ = (colors[index]<<32) | colors1[index1]; | |||
-# else | |||
- *q++ = (colors1[index1]<<32) | colors[index]; | |||
-# endif | |||
- } else { | |||
-# if WORDS_BIGENDIAN | |||
- *q++ = colors[index]<<32; | |||
-# else | |||
- *q++ = colors[index]; | |||
-# endif | |||
- } | |||
- } | |||
-} | |||
- | |||
-#else // U32 | |||
- | |||
-// The callback from fl_draw_image to get a row of data passes this: | |||
-struct pixmap_data { | |||
- int w, h; | |||
- const uchar*const* data; | |||
- union { | |||
- U32 colors[256]; | |||
- U32* byte1[256]; | |||
- }; | |||
-}; | |||
- | |||
-// callback for 1 byte per pixel: | |||
-static void cb1(void*v, int x, int y, int w, uchar* buf) { | |||
- pixmap_data& d = *(pixmap_data*)v; | |||
- const uchar* p = d.data[y]+x; | |||
- U32* q = (U32*)buf; | |||
- for (int X=w; X--;) *q++ = d.colors[*p++]; | |||
-} | |||
- | |||
-// callback for 2 bytes per pixel: | |||
-static void cb2(void*v, int x, int y, int w, uchar* buf) { | |||
- pixmap_data& d = *(pixmap_data*)v; | |||
- const uchar* p = d.data[y]+2*x; | |||
- U32* q = (U32*)buf; | |||
- for (int X=w; X--;) { | |||
- U32* colors = d.byte1[*p++]; | |||
- *q++ = colors[*p++]; | |||
- } | |||
-} | |||
- | |||
-#endif // U64 else U32 | |||
- | |||
uchar **fl_mask_bitmap; // if non-zero, create bitmap and store pointer here | |||
/** | |||
@@ -200,34 +107,33 @@ | |||
} | |||
#endif | |||
-/** | |||
- Draw XPM image data, with the top-left corner at the given position. | |||
- \see fl_draw_pixmap(char* const* data, int x, int y, Fl_Color bg) | |||
- */ | |||
-int fl_draw_pixmap(const char*const* cdata, int x, int y, Fl_Color bg) { | |||
- pixmap_data d; | |||
- if (!fl_measure_pixmap(cdata, d.w, d.h)) return 0; | |||
+int fl_convert_pixmap(const char*const* cdata, uchar* out, Fl_Color bg) { | |||
+ int w, h; | |||
const uchar*const* data = (const uchar*const*)(cdata+1); | |||
int transparent_index = -1; | |||
+ | |||
+ if (!fl_measure_pixmap(cdata, w, h)) | |||
+ return 0; | |||
+ | |||
+ if ((chars_per_pixel < 1) || (chars_per_pixel > 2)) | |||
+ return 0; | |||
+ | |||
+ uchar colors[1<<(chars_per_pixel*8)][4]; | |||
+ | |||
#ifdef WIN32 | |||
uchar *transparent_c = (uchar *)0; // such that transparent_c[0,1,2] are the RGB of the transparent color | |||
color_count = 0; | |||
used_colors = (uchar *)malloc(abs(ncolors)*3*sizeof(uchar)); | |||
#endif | |||
- if (ncolors < 0) { // FLTK (non standard) compressed colormap | |||
+ if (ncolors < 0) { | |||
+ // FLTK (non standard) compressed colormap | |||
ncolors = -ncolors; | |||
const uchar *p = *data++; | |||
// if first color is ' ' it is transparent (put it later to make | |||
// it not be transparent): | |||
if (*p == ' ') { | |||
- uchar* c = (uchar*)&d.colors[(int)' ']; | |||
-#ifdef U64 | |||
- *(U64*)c = 0; | |||
-# if WORDS_BIGENDIAN | |||
- c += 4; | |||
-# endif | |||
-#endif | |||
+ uchar* c = colors[(int)' ']; | |||
transparent_index = ' '; | |||
Fl::get_color(bg, c[0], c[1], c[2]); c[3] = 0; | |||
#ifdef WIN32 | |||
@@ -238,13 +144,7 @@ | |||
} | |||
// read all the rest of the colors: | |||
for (int i=0; i < ncolors; i++) { | |||
- uchar* c = (uchar*)&d.colors[*p++]; | |||
-#ifdef U64 | |||
- *(U64*)c = 0; | |||
-# if WORDS_BIGENDIAN | |||
- c += 4; | |||
-# endif | |||
-#endif | |||
+ uchar* c = colors[*p++]; | |||
#ifdef WIN32 | |||
used_colors[3*color_count] = *p; | |||
used_colors[3*color_count+1] = *(p+1); | |||
@@ -254,69 +154,44 @@ | |||
*c++ = *p++; | |||
*c++ = *p++; | |||
*c++ = *p++; | |||
-#ifdef __APPLE_QUARTZ__ | |||
*c = 255; | |||
-#else | |||
- *c = 0; | |||
-#endif | |||
} | |||
- } else { // normal XPM colormap with names | |||
- if (chars_per_pixel>1) memset(d.byte1, 0, sizeof(d.byte1)); | |||
+ } else { | |||
+ // normal XPM colormap with names | |||
for (int i=0; i<ncolors; i++) { | |||
const uchar *p = *data++; | |||
// the first 1 or 2 characters are the color index: | |||
int ind = *p++; | |||
uchar* c; | |||
- if (chars_per_pixel>1) { | |||
-#ifdef U64 | |||
- U64* colors = d.byte1[ind]; | |||
- if (!colors) colors = d.byte1[ind] = new U64[256]; | |||
-#else | |||
- U32* colors = d.byte1[ind]; | |||
- if (!colors) colors = d.byte1[ind] = new U32[256]; | |||
-#endif | |||
- c = (uchar*)&colors[*p]; | |||
- ind = (ind<<8)|*p++; | |||
- } else { | |||
- c = (uchar *)&d.colors[ind]; | |||
- } | |||
+ if (chars_per_pixel>1) | |||
+ ind = (ind<<8)|*p++; | |||
+ c = colors[ind]; | |||
// look for "c word", or last word if none: | |||
const uchar *previous_word = p; | |||
for (;;) { | |||
- while (*p && isspace(*p)) p++; | |||
- uchar what = *p++; | |||
- while (*p && !isspace(*p)) p++; | |||
- while (*p && isspace(*p)) p++; | |||
- if (!*p) {p = previous_word; break;} | |||
- if (what == 'c') break; | |||
- previous_word = p; | |||
- while (*p && !isspace(*p)) p++; | |||
+ while (*p && isspace(*p)) p++; | |||
+ uchar what = *p++; | |||
+ while (*p && !isspace(*p)) p++; | |||
+ while (*p && isspace(*p)) p++; | |||
+ if (!*p) {p = previous_word; break;} | |||
+ if (what == 'c') break; | |||
+ previous_word = p; | |||
+ while (*p && !isspace(*p)) p++; | |||
} | |||
-#ifdef U64 | |||
- *(U64*)c = 0; | |||
-# if WORDS_BIGENDIAN | |||
- c += 4; | |||
-# endif | |||
-#endif | |||
-#ifdef __APPLE_QUARTZ__ | |||
- c[3] = 255; | |||
-#endif | |||
int parse = fl_parse_color((const char*)p, c[0], c[1], c[2]); | |||
+ c[3] = 255; | |||
if (parse) { | |||
#ifdef WIN32 | |||
- used_colors[3*color_count] = c[0]; | |||
- used_colors[3*color_count+1] = c[1]; | |||
- used_colors[3*color_count+2] = c[2]; | |||
- color_count++; | |||
+ used_colors[3*color_count] = c[0]; | |||
+ used_colors[3*color_count+1] = c[1]; | |||
+ used_colors[3*color_count+2] = c[2]; | |||
+ color_count++; | |||
#endif | |||
- } | |||
- else { | |||
+ } else { | |||
// assume "None" or "#transparent" for any errors | |||
- // "bg" should be transparent... | |||
- Fl::get_color(bg, c[0], c[1], c[2]); | |||
-#ifdef __APPLE_QUARTZ__ | |||
+ // "bg" should be transparent... | |||
+ Fl::get_color(bg, c[0], c[1], c[2]); | |||
c[3] = 0; | |||
-#endif | |||
transparent_index = ind; | |||
#ifdef WIN32 | |||
transparent_c = c; | |||
@@ -324,7 +199,6 @@ | |||
} | |||
} | |||
} | |||
- d.data = data; | |||
#ifdef WIN32 | |||
if (transparent_c) { | |||
make_unused_color(transparent_c[0], transparent_c[1], transparent_c[2]); | |||
@@ -334,77 +208,76 @@ | |||
make_unused_color(r, g, b); | |||
} | |||
#endif | |||
+ | |||
+ U32 *q = (U32*)out; | |||
+ for (int Y = 0; Y < h; Y++) { | |||
+ const uchar* p = data[Y]; | |||
+ if (chars_per_pixel <= 1) { | |||
+ for (int X = 0; X < w; X++) | |||
+ memcpy(q++, colors[*p++], 4); | |||
+ } else { | |||
+ for (int X = 0; X < w; X++) { | |||
+ int ind = (*p++)<<8; | |||
+ ind |= *p++; | |||
+ memcpy(q++, colors[ind], 4); | |||
+ } | |||
+ } | |||
+ } | |||
+ return 1; | |||
+} | |||
+ | |||
+/** | |||
+ Draw XPM image data, with the top-left corner at the given position. | |||
+ \see fl_draw_pixmap(char* const* data, int x, int y, Fl_Color bg) | |||
+ */ | |||
+int fl_draw_pixmap(const char*const* cdata, int x, int y, Fl_Color bg) { | |||
+ int w, h; | |||
+ | |||
+ if (!fl_measure_pixmap(cdata, w, h)) | |||
+ return 0; | |||
+ | |||
+ uchar buffer[w*h*4]; | |||
+ | |||
+ if (!fl_convert_pixmap(cdata, buffer, bg)) | |||
+ return 0; | |||
+ | |||
+ // FIXME: Hack until fl_draw_image() supports alpha properly | |||
#ifdef __APPLE_QUARTZ__ | |||
if (Fl_Surface_Device::surface() == Fl_Display_Device::display_device()) { | |||
- U32 *array = new U32[d.w * d.h], *q = array; | |||
- for (int Y = 0; Y < d.h; Y++) { | |||
- const uchar* p = data[Y]; | |||
- if (chars_per_pixel <= 1) { | |||
- for (int X = 0; X < d.w; X++) { | |||
- *q++ = d.colors[*p++]; | |||
- } | |||
- } else { | |||
- for (int X = 0; X < d.w; X++) { | |||
- U32* colors = (U32*)d.byte1[*p++]; | |||
- *q++ = colors[*p++]; | |||
- } | |||
- } | |||
- } | |||
- Fl_RGB_Image* rgb = new Fl_RGB_Image((uchar*)array, d.w, d.h, 4); | |||
+ Fl_RGB_Image* rgb = new Fl_RGB_Image(buffer, w, h, 4); | |||
rgb->draw(x, y); | |||
delete rgb; | |||
- delete[] array; | |||
- } | |||
- else { | |||
+ } else { | |||
#endif // __APPLE_QUARTZ__ | |||
- | |||
// build the mask bitmap used by Fl_Pixmap: | |||
- if (fl_mask_bitmap && transparent_index >= 0) { | |||
- int W = (d.w+7)/8; | |||
- uchar* bitmap = new uchar[W * d.h]; | |||
+ if (fl_mask_bitmap) { | |||
+ int W = (w+7)/8; | |||
+ uchar* bitmap = new uchar[W * h]; | |||
*fl_mask_bitmap = bitmap; | |||
- for (int Y = 0; Y < d.h; Y++) { | |||
- const uchar* p = data[Y]; | |||
- if (chars_per_pixel <= 1) { | |||
- int dw = d.w; | |||
- for (int X = 0; X < W; X++) { | |||
- uchar b = (dw-->0 && *p++ != transparent_index); | |||
- if (dw-->0 && *p++ != transparent_index) b |= 2; | |||
- if (dw-->0 && *p++ != transparent_index) b |= 4; | |||
- if (dw-->0 && *p++ != transparent_index) b |= 8; | |||
- if (dw-->0 && *p++ != transparent_index) b |= 16; | |||
- if (dw-->0 && *p++ != transparent_index) b |= 32; | |||
- if (dw-->0 && *p++ != transparent_index) b |= 64; | |||
- if (dw-->0 && *p++ != transparent_index) b |= 128; | |||
+ const uchar *p = &buffer[3]; | |||
+ uchar b = 0; | |||
+ for (int Y = 0; Y < h; Y++) { | |||
+ b = 0; | |||
+ for (int X = 0, bit = 1; X < w; X++, p += 4) { | |||
+ if (*p > 127) b |= bit; | |||
+ bit <<= 1; | |||
+ if (bit > 0x80 || X == w-1) { | |||
*bitmap++ = b; | |||
- } | |||
- } else { | |||
- uchar b = 0, bit = 1; | |||
- for (int X = 0; X < d.w; X++) { | |||
- int ind = *p++; | |||
- ind = (ind<<8) | (*p++); | |||
- if (ind != transparent_index) b |= bit; | |||
- | |||
- if (bit < 128) bit <<= 1; | |||
- else { | |||
- *bitmap++ = b; | |||
- b = 0; | |||
- bit = 1; | |||
+ bit = 1; | |||
+ b = 0; | |||
} | |||
} | |||
- | |||
- if (bit > 1) *bitmap++ = b; | |||
} | |||
- } | |||
+ | |||
} | |||
- fl_draw_image(chars_per_pixel==1 ? cb1 : cb2, &d, x, y, d.w, d.h, 4); | |||
+ fl_draw_image(buffer, x, y, w, h, 4); | |||
+ | |||
#ifdef __APPLE_QUARTZ__ | |||
} | |||
#endif | |||
- if (chars_per_pixel > 1) for (int i = 0; i < 256; i++) delete[] d.byte1[i]; | |||
return 1; | |||
} | |||
diff -ur fltk-1.3.2.org/src/Fl_Image.cxx fltk-1.3.2/src/Fl_Image.cxx | |||
--- fltk-1.3.2.org/src/Fl_Image.cxx 2012-11-09 17:02:08.000000000 +0100 | |||
+++ fltk-1.3.2/src/Fl_Image.cxx 2013-01-16 14:41:38.404162795 +0100 | |||
@@ -165,7 +165,22 @@ | |||
// | |||
size_t Fl_RGB_Image::max_size_ = ~((size_t)0); | |||
-/** The destructor free all memory and server resources that are used by the image. */ | |||
+int fl_convert_pixmap(const char*const* cdata, uchar* out, Fl_Color bg); | |||
+ | |||
+/** The constructor creates a new RGBA image from the specified Fl_Pixmap. | |||
+ | |||
+ The RGBA image is built fully opaque except for the transparent area | |||
+ of the pixmap that is assigned the \par bg color with full transparency */ | |||
+Fl_RGB_Image::Fl_RGB_Image(const Fl_Pixmap *pxm, Fl_Color bg): | |||
+ Fl_Image(pxm->w(), pxm->h(), 4), id_(0), mask_(0) | |||
+{ | |||
+ array = new uchar[w() * h() * d()]; | |||
+ alloc_array = 1; | |||
+ fl_convert_pixmap(pxm->data(), (uchar*)array, bg); | |||
+ data((const char **)&array, 1); | |||
+} | |||
+ | |||
+/** The destructor frees all memory and server resources that are used by the image. */ | |||
Fl_RGB_Image::~Fl_RGB_Image() { | |||
uncache(); | |||
if (alloc_array) delete[] (uchar *)array; | |||
diff -ur fltk-1.3.2.org/src/ps_image.cxx fltk-1.3.2/src/ps_image.cxx | |||
--- fltk-1.3.2.org/src/ps_image.cxx 2011-07-19 06:49:30.000000000 +0200 | |||
+++ fltk-1.3.2/src/ps_image.cxx 2013-01-16 14:40:51.541228080 +0100 | |||
@@ -185,72 +185,38 @@ | |||
extern uchar **fl_mask_bitmap; | |||
+struct callback_data { | |||
+ const uchar *data; | |||
+ int D, LD; | |||
+}; | |||
-void Fl_PostScript_Graphics_Driver::draw_image(const uchar *data, int ix, int iy, int iw, int ih, int D, int LD) { | |||
- double x = ix, y = iy, w = iw, h = ih; | |||
- if (D<3){ //mono | |||
- draw_image_mono(data, ix, iy, iw, ih, D, LD); | |||
- return; | |||
- } | |||
+static void draw_image_cb(void *data, int x, int y, int w, uchar *buf) { | |||
+ struct callback_data *cb_data; | |||
+ const uchar *curdata; | |||
+ cb_data = (struct callback_data*)data; | |||
+ curdata = cb_data->data + x*cb_data->D + y*cb_data->LD; | |||
- int i,j, k; | |||
+ memcpy(buf, curdata, w*cb_data->D); | |||
+} | |||
- fprintf(output,"save\n"); | |||
- const char * interpol; | |||
- if (lang_level_>1){ | |||
- if (interpolate_) | |||
- interpol="true"; | |||
- else | |||
- interpol="false"; | |||
- if (mask && lang_level_>2) | |||
- fprintf(output, "%g %g %g %g %i %i %i %i %s CIM\n", x , y+h , w , -h , iw , ih, mx, my, interpol); | |||
- else | |||
- fprintf(output, "%g %g %g %g %i %i %s CII\n", x , y+h , w , -h , iw , ih, interpol); | |||
- } else | |||
- fprintf(output , "%g %g %g %g %i %i CI", x , y+h , w , -h , iw , ih); | |||
+void Fl_PostScript_Graphics_Driver::draw_image(const uchar *data, int ix, int iy, int iw, int ih, int D, int LD) { | |||
+ if (D<3){ //mono | |||
+ draw_image_mono(data, ix, iy, iw, ih, D, LD); | |||
+ return; | |||
+ } | |||
+ struct callback_data cb_data; | |||
if (!LD) LD = iw*D; | |||
- uchar *curmask=mask; | |||
- | |||
- for (j=0; j<ih;j++){ | |||
- if (mask){ | |||
- | |||
- for (k=0;k<my/ih;k++){ | |||
- for (i=0; i<((mx+7)/8);i++){ | |||
- if (!(i%80)) fprintf(output, "\n"); | |||
- fprintf(output, "%.2x",swap_byte(*curmask)); | |||
- curmask++; | |||
- } | |||
- fprintf(output,"\n"); | |||
- } | |||
- } | |||
- const uchar *curdata=data+j*LD; | |||
- for (i=0 ; i<iw ; i++) { | |||
- uchar r = curdata[0]; | |||
- uchar g = curdata[1]; | |||
- uchar b = curdata[2]; | |||
- if (lang_level_<3 && D>3) { //can do mixing using bg_* colors) | |||
- unsigned int a2 = curdata[3]; //must be int | |||
- unsigned int a = 255-a2; | |||
- r = (a2 * r + bg_r * a)/255; | |||
- g = (a2 * g + bg_g * a)/255; | |||
- b = (a2 * b + bg_b * a)/255; | |||
- } | |||
- if (!(i%40)) fprintf(output, "\n"); | |||
- fprintf(output, "%.2x%.2x%.2x", r, g, b); | |||
- curdata +=D; | |||
- } | |||
- fprintf(output,"\n"); | |||
- | |||
- } | |||
- | |||
- fprintf(output," >\nrestore\n" ); | |||
+ cb_data.data = data; | |||
+ cb_data.D = D; | |||
+ cb_data.LD = LD; | |||
+ draw_image(draw_image_cb, &cb_data, ix, iy, iw, ih, D); | |||
} | |||
void Fl_PostScript_Graphics_Driver::draw_image(Fl_Draw_Image_Cb call, void *data, int ix, int iy, int iw, int ih, int D) { | |||
@@ -325,6 +291,14 @@ | |||
uchar g = curdata[1]; | |||
uchar b = curdata[2]; | |||
+ if (lang_level_<3 && D>3) { //can do mixing using bg_* colors) | |||
+ unsigned int a2 = curdata[3]; //must be int | |||
+ unsigned int a = 255-a2; | |||
+ r = (a2 * r + bg_r * a)/255; | |||
+ g = (a2 * g + bg_g * a)/255; | |||
+ b = (a2 * b + bg_b * a)/255; | |||
+ } | |||
+ | |||
if (!(i%40)) fputs("\n", output); | |||
fprintf(output, "%.2x%.2x%.2x", r, g, b); | |||
@@ -0,0 +1,15 @@ | |||
diff --git a/m4/shave.m4 b/m4/shave.m4 | |||
index 01cb5c7..0dfde6c 100644 | |||
--- a/m4/shave.m4 | |||
+++ b/m4/shave.m4 | |||
@@ -32,8 +32,8 @@ AC_DEFUN([SHAVE_INIT], | |||
if test x"$enable_shave" = xyes; then | |||
dnl where can we find the shave scripts? | |||
m4_if([$1],, | |||
- [shavedir="$ac_pwd"], | |||
- [shavedir="$ac_pwd/$1"]) | |||
+ [shavedir=`pwd`], | |||
+ [shavedir=`pwd`/$1]) | |||
AC_SUBST(shavedir) | |||
dnl make is now quiet |
@@ -0,0 +1,37 @@ | |||
diff -up tigervnc-1.0.90-20091221svn3929/unix/vncserver.cookie tigervnc-1.0.90-20091221svn3929/unix/vncserver | |||
--- tigervnc-1.0.90-20091221svn3929/unix/vncserver.cookie 2009-11-12 11:39:54.000000000 +0100 | |||
+++ tigervnc-1.0.90-20091221svn3929/unix/vncserver 2009-12-21 16:15:01.907799091 +0100 | |||
@@ -189,27 +189,12 @@ $vncPort = 5900 + $displayNumber; | |||
$desktopLog = "$vncUserDir/$host:$displayNumber.log"; | |||
unlink($desktopLog); | |||
-# Make an X server cookie - use /dev/urandom on systems that have it, | |||
-# otherwise use perl's random number generator, seeded with the sum | |||
-# of the current time, our PID and part of the encrypted form of the password. | |||
- | |||
-my $cookie = ""; | |||
-if (open(URANDOM, '<', '/dev/urandom')) { | |||
- my $randata; | |||
- if (sysread(URANDOM, $randata, 16) == 16) { | |||
- $cookie = unpack 'h*', $randata; | |||
- } | |||
- close(URANDOM); | |||
-} | |||
-if ($cookie eq "") { | |||
- srand(time+$$+unpack("L",`cat $vncUserDir/passwd`)); | |||
- for (1..16) { | |||
- $cookie .= sprintf("%02x", int(rand(256)) % 256); | |||
- } | |||
-} | |||
- | |||
-system("xauth -f $xauthorityFile add $host:$displayNumber . $cookie"); | |||
-system("xauth -f $xauthorityFile add $host/unix:$displayNumber . $cookie"); | |||
+# Make an X server cookie - use mcookie | |||
+$cookie = `/usr/bin/mcookie`; | |||
+open (XAUTH, "|xauth -f $xauthorityFile source -"); | |||
+print XAUTH "add $host:$displayNumber . $cookie\n"; | |||
+print XAUTH "add $host/unix:$displayNumber . $cookie\n"; | |||
+close XAUTH; | |||
if ($opt{'-name'}) { | |||
$desktopName = $opt{'-name'}; |
@@ -0,0 +1,33 @@ | |||
--- a/dix/dixutils.c 2012-06-28 11:06:25.676773000 -0400 | |||
+++ b/dix/dixutils.c 2012-06-28 11:07:05.224177000 -0400 | |||
@@ -165,16 +165,6 @@ | |||
} | |||
-void | |||
-CopyISOLatin1Lowered(unsigned char *dest, unsigned char *source, int length) | |||
-{ | |||
- int i; | |||
- | |||
- for (i = 0; i < length; i++, source++, dest++) | |||
- *dest = ISOLatin1ToLower (*source); | |||
- *dest = '\0'; | |||
-} | |||
- | |||
int | |||
CompareISOLatin1Lowered(unsigned char *s1, int s1len, | |||
unsigned char *s2, int s2len) | |||
--- a/include/dix.h 2012-06-28 11:07:38.135955000 -0400 | |||
+++ b/include/dix.h 2012-06-28 11:07:45.120547000 -0400 | |||
@@ -173,11 +173,6 @@ | |||
extern _X_HIDDEN Bool CreateConnectionBlock(void); | |||
/* dixutils.c */ | |||
-extern _X_EXPORT void CopyISOLatin1Lowered( | |||
- unsigned char * /*dest*/, | |||
- unsigned char * /*source*/, | |||
- int /*length*/); | |||
- | |||
extern _X_EXPORT int CompareISOLatin1Lowered( | |||
unsigned char * /*a*/, | |||
int alen, |
@@ -0,0 +1,20 @@ | |||
diff -up tigervnc-1.0.90/unix/xserver/hw/vnc/Makefile.am.gethomedir tigervnc-1.0.90/unix/xserver/hw/vnc/Makefile.am | |||
--- tigervnc-1.0.90/unix/xserver/hw/vnc/Makefile.am.gethomedir 2011-03-22 10:53:05.206429397 +0100 | |||
+++ tigervnc-1.0.90/unix/xserver/hw/vnc/Makefile.am 2011-03-22 10:53:30.550388457 +0100 | |||
@@ -5,6 +5,7 @@ RFB_LIB=$(LIB_DIR)/rfb/librfb.la | |||
RDR_LIB=$(LIB_DIR)/rdr/librdr.la $(GNUTLS_LDFLAGS) | |||
NETWORK_LIB=$(LIB_DIR)/network/libnetwork.la | |||
XREGION_LIB=$(LIB_DIR)/Xregion/libXregion.la | |||
+OS_LIB=$(LIB_DIR)/os/libos.la | |||
COMMON_LIBS=$(NETWORK_LIB) $(RFB_LIB) $(RDR_LIB) $(XREGION_LIB) | |||
noinst_LTLIBRARIES = libvnccommon.la | |||
@@ -52,7 +53,7 @@ libvnc_la_CPPFLAGS = $(XVNC_CPPFLAGS) -I | |||
libvnc_la_LDFLAGS = -module -avoid-version -Wl,-z,now | |||
-libvnc_la_LIBADD = libvnccommon.la $(COMMON_LIBS) | |||
+libvnc_la_LIBADD = libvnccommon.la $(COMMON_LIBS) $(OS_LIB) | |||
EXTRA_DIST = Xvnc.man | |||
@@ -0,0 +1,12 @@ | |||
diff -up tigervnc-1.0.90-20100721svn4113/unix/xserver/hw/vnc/Makefile.am.ldnow tigervnc-1.0.90-20100721svn4113/unix/xserver/hw/vnc/Makefile.am | |||
--- tigervnc-1.0.90-20100721svn4113/unix/xserver/hw/vnc/Makefile.am.ldnow 2010-05-18 15:48:02.000000000 +0200 | |||
+++ tigervnc-1.0.90-20100721svn4113/unix/xserver/hw/vnc/Makefile.am 2010-07-21 17:05:45.242942531 +0200 | |||
@@ -50,7 +50,7 @@ libvnc_la_CPPFLAGS = $(XVNC_CPPFLAGS) -I | |||
-I$(top_srcdir)/hw/xfree86/os-support/bus \ | |||
-I$(includedir)/pixman-1 -I$(includedir) | |||
-libvnc_la_LDFLAGS = -module -avoid-version | |||
+libvnc_la_LDFLAGS = -module -avoid-version -Wl,-z,now | |||
libvnc_la_LIBADD = libvnccommon.la $(COMMON_LIBS) | |||
@@ -0,0 +1,44 @@ | |||
diff -up tigervnc-1.0.90-20110314svn4359/common/rfb/SecurityClient.cxx.rh690245 tigervnc-1.0.90-20110314svn4359/common/rfb/SecurityClient.cxx | |||
--- tigervnc-1.0.90-20110314svn4359/common/rfb/SecurityClient.cxx.rh690245 2011-02-21 14:14:16.000000000 +0100 | |||
+++ tigervnc-1.0.90-20110314svn4359/common/rfb/SecurityClient.cxx 2011-03-31 09:47:34.519099718 +0200 | |||
@@ -45,7 +45,7 @@ StringParameter SecurityClient::secTypes | |||
("SecurityTypes", | |||
"Specify which security scheme to use (None, VncAuth)", | |||
#ifdef HAVE_GNUTLS | |||
- "X509Plain,TLSPlain,X509Vnc,TLSVnc,X509None,TLSNone,VncAuth,None", | |||
+ "VeNCrypt,X509Plain,TLSPlain,X509Vnc,TLSVnc,X509None,TLSNone,VncAuth,None", | |||
#else | |||
"VncAuth,None", | |||
#endif | |||
diff -up tigervnc-1.0.90-20110314svn4359/common/rfb/Security.cxx.rh690245 tigervnc-1.0.90-20110314svn4359/common/rfb/Security.cxx | |||
--- tigervnc-1.0.90-20110314svn4359/common/rfb/Security.cxx.rh690245 2011-02-21 14:14:16.000000000 +0100 | |||
+++ tigervnc-1.0.90-20110314svn4359/common/rfb/Security.cxx 2011-03-31 09:47:34.519099718 +0200 | |||
@@ -67,7 +67,6 @@ const std::list<rdr::U8> Security::GetEn | |||
list<rdr::U8> result; | |||
list<U32>::iterator i; | |||
- result.push_back(secTypeVeNCrypt); | |||
for (i = enabledSecTypes.begin(); i != enabledSecTypes.end(); i++) | |||
if (*i < 0x100) | |||
result.push_back(*i); | |||
@@ -105,8 +104,6 @@ bool Security::IsSupported(U32 secType) | |||
for (i = enabledSecTypes.begin(); i != enabledSecTypes.end(); i++) | |||
if (*i == secType) | |||
return true; | |||
- if (secType == secTypeVeNCrypt) | |||
- return true; | |||
return false; | |||
} | |||
diff -up tigervnc-1.0.90-20110314svn4359/common/rfb/SecurityServer.cxx.rh690245 tigervnc-1.0.90-20110314svn4359/common/rfb/SecurityServer.cxx | |||
--- tigervnc-1.0.90-20110314svn4359/common/rfb/SecurityServer.cxx.rh690245 2011-02-21 14:50:17.000000000 +0100 | |||
+++ tigervnc-1.0.90-20110314svn4359/common/rfb/SecurityServer.cxx 2011-03-31 10:06:43.595362302 +0200 | |||
@@ -39,7 +39,7 @@ StringParameter SecurityServer::secTypes | |||
("SecurityTypes", | |||
"Specify which security scheme to use (None, VncAuth)", | |||
#ifdef HAVE_GNUTLS | |||
- "VncAuth,TLSVnc", | |||
+ "VncAuth", | |||
#else | |||
"VncAuth", | |||
#endif |
@@ -0,0 +1,91 @@ | |||
#!/bin/bash | |||
# | |||
# Init file for TigerVNC Server | |||
# | |||
# Written by Dag Wieers <dag@wieers.com> | |||
# | |||
# chkconfig: - 91 35 | |||
# description: TigerVNC remote X administration daemon. | |||
# | |||
# processname: Xvnc | |||
source /etc/rc.d/init.d/functions | |||
source /etc/sysconfig/network | |||
# Check that networking is up. | |||
[ ${NETWORKING} = "no" ] && exit 1 | |||
[ -x /usr/bin/Xvnc ] || exit 1 | |||
### Default variables | |||
SYSCONFIG="/etc/sysconfig/vncservers" | |||
VNCSERVERS="" | |||
### Read configuration | |||
[ -r "$SYSCONFIG" ] && source "$SYSCONFIG" | |||
RETVAL=0 | |||
prog="Xvnc" | |||
desc="TigerVNC remote administration daemon" | |||
start() { | |||
echo -n $"Starting $desc ($prog):" | |||
ulimit -S -c 0 &>/dev/null | |||
for display in ${VNCSERVERS}; do | |||
echo -n "${display} " | |||
unset BASH_ENV ENV | |||
initlog $INITLOG_ARGS -c \ | |||
"su ${display##*:} -c \"cd ~${display##*:} && [ -f .vnc/passwd ] && vncserver :${display%:*} ${VNCSERVERARGS[${display%:*}]}\"" | |||
RETVAL=$? | |||
[ "$RETVAL" -ne 0 ] && break | |||
done | |||
[ "$RETVAL" -eq 0 ] && success $"vncserver startup" || failure $"vncserver start" | |||
echo | |||
[ "$RETVAL" -eq 0 ] && touch /var/lock/subsys/$prog | |||
return $RETVAL | |||
} | |||
stop() { | |||
echo -n $"Shutting down $desc ($prog): " | |||
for display in ${VNCSERVERS}; do | |||
echo -n "${display} " | |||
unset BASH_ENV ENV | |||
initlog $INITLOG_ARGS -c \ | |||
"su ${display##*:} -c \"vncserver -kill :${display%:*}\" &>/dev/null" | |||
done | |||
RETVAL=$? | |||
[ "$RETVAL" -eq 0 ] && success $"vncserver shutdown" || failure $"vncserver shutdown" | |||
echo | |||
[ "$RETVAL" -eq 0 ] && rm -f /var/lock/subsys/$prog | |||
return $RETVAL | |||
} | |||
restart() { | |||
stop | |||
start | |||
} | |||
case "$1" in | |||
start) | |||
start | |||
;; | |||
stop) | |||
stop | |||
;; | |||
restart|reload) | |||
restart | |||
;; | |||
condrestart) | |||
[ -e /var/lock/subsys/$prog ] && restart | |||
RETVAL=$? | |||
;; | |||
status) | |||
status $prog | |||
RETVAL=$? | |||
;; | |||
*) | |||
echo $"Usage: $0 {start|stop|restart|condrestart|status}" | |||
RETVAL=1 | |||
esac | |||
exit $RETVAL |
@@ -0,0 +1,19 @@ | |||
# The VNCSERVERS variable is a list of display:user pairs. | |||
# | |||
# Uncomment the lines below to start a VNC server on display :2 | |||
# as my 'myusername' (adjust this to your own). You will also | |||
# need to set a VNC password; run 'man vncpasswd' to see how | |||
# to do that. | |||
# | |||
# DO NOT RUN THIS SERVICE if your local area network is | |||
# untrusted! For a secure way of using VNC, see this URL: | |||
# http://kbase.redhat.com/faq/docs/DOC-7028 | |||
# Use "-nolisten tcp" to prevent X connections to your VNC server via TCP. | |||
# Use "-localhost" to prevent remote VNC clients connecting except when | |||
# doing so through a secure tunnel. See the "-via" option in the | |||
# `man vncviewer' manual page. | |||
# VNCSERVERS="2:myusername" | |||
# VNCSERVERARGS[2]="-geometry 800x600 -nolisten tcp -localhost" |