Moved the SGML documentation over to SourceForge.
This commit is contained in:
parent
15ac6847e0
commit
12f9bb7ab2
40 changed files with 8 additions and 23997 deletions
36
README
36
README
|
@ -19,10 +19,8 @@ of the Wine source (which contains this file), run:
|
|||
./tools/wineinstall
|
||||
|
||||
Run programs as "wine [options] program". For more information and
|
||||
problem resolution, read the rest of this file, the Wine man page,
|
||||
the files in the documentation directory of the Wine source
|
||||
(see "DOCUMENTATION"), and especially the wealth of information
|
||||
found at http://www.winehq.org.
|
||||
problem resolution, read the rest of this file, the Wine man page, and
|
||||
especially the wealth of information found at http://www.winehq.org.
|
||||
|
||||
3. REQUIREMENTS
|
||||
|
||||
|
@ -90,9 +88,6 @@ Optional support libraries:
|
|||
If you want CUPS printing support, please install both cups and cups-devel
|
||||
packages.
|
||||
|
||||
For requirements in case you intend to build the documentation yourself,
|
||||
see "DOCUMENTATION" section.
|
||||
|
||||
4. COMPILATION
|
||||
|
||||
In case you chose to not use wineinstall, run the following commands
|
||||
|
@ -129,17 +124,8 @@ Don't forget to uninstall any conflicting previous Wine installation
|
|||
first. Try either "dpkg -r wine" or "rpm -e wine" or "make uninstall"
|
||||
before installing.
|
||||
|
||||
If you want to read the documentation supplied with the Wine source,
|
||||
see the "DOCUMENTATION" section.
|
||||
|
||||
Wine requires a configuration file named named "config" in your
|
||||
~/.wine directory. The format of this file is explained in the config file
|
||||
man page (documentation/wine.conf.man).
|
||||
The file documentation/samples/config contains an example configuration file
|
||||
which has to be adapted and copied to the location mentioned above.
|
||||
|
||||
See the Support area at http://www.winehq.org/ for further
|
||||
configuration hints.
|
||||
See the Support area at http://www.winehq.org/ for configuration
|
||||
hints.
|
||||
|
||||
In case of library loading errors
|
||||
(e.g. "Error while loading shared libraries: libntdll.so"), make sure
|
||||
|
@ -180,19 +166,7 @@ as they launch Explorer somehow. This particular corruption (!$!$!$!$.pfr)
|
|||
can at least partially be fixed by using
|
||||
http://home.nexgo.de/andi.mohr/download/decorrupt_explorer
|
||||
|
||||
7. DOCUMENTATION
|
||||
|
||||
Some documentation (various Wine Guides etc.) can be found in the
|
||||
documentation/ directory (apart from also being available on WineHQ).
|
||||
|
||||
If you want to process the SGML files in there, then you can run "make doc"
|
||||
in the documentation/ directory.
|
||||
Doing so requires the sgml tools package (for db2html, db2ps, db2pdf) named:
|
||||
Debian: docbook-utils
|
||||
Mandrake: sgml-tools-A.B.C-DDmdk
|
||||
SuSE: docbktls-A.BB.C-DD
|
||||
|
||||
8. GETTING MORE INFORMATION
|
||||
7. GETTING MORE INFORMATION
|
||||
|
||||
WWW: A great deal of information about Wine is available from WineHQ at
|
||||
http://www.winehq.org/ : various Wine Guides, application database,
|
||||
|
|
170
configure
vendored
170
configure
vendored
|
@ -311,7 +311,7 @@ ac_includes_default="\
|
|||
# include <unistd.h>
|
||||
#endif"
|
||||
|
||||
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS WIN16_FILES WIN16_INSTALL DLLDEFS build build_cpu build_vendor build_os host host_cpu host_vendor host_os SET_MAKE CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CXX CXXFLAGS ac_ct_CXX CPPBIN ac_ct_CPPBIN TOOLSDIR CPP X_CFLAGS X_PRE_LIBS X_LIBS X_EXTRA_LIBS LEX LEXLIB LEX_OUTPUT_ROOT XLEX BISON AS ac_ct_AS LD ac_ct_LD AR ac_ct_AR RANLIB ac_ct_RANLIB STRIP ac_ct_STRIP WINDRES ac_ct_WINDRES LN_S LN EGREP LDCONFIG INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LINT LINTFLAGS DB2HTML DB2PDF DB2PS DB2TXT FONTFORGE LIBPTHREAD XLIB XFILES OPENGLFILES GLU32FILES OPENGL_LIBS GLUT_LIBS GLUT32FILES NASLIBS CURSESLIBS sane_devel SANELIBS SANEINCL ICULIBS ft_devel ft_devel2 FREETYPELIBS FREETYPEINCL FONTSSUBDIRS ARTSCCONFIG ARTSLIBS ARTSINCL ALSALIBS AUDIOIOLIBS EXTRACFLAGS DLLEXT DLLFLAGS DLLIBS LDSHARED LDDLLFLAGS LIBEXT IMPLIBEXT DLLTOOL ac_ct_DLLTOOL DLLWRAP ac_ct_DLLWRAP LDEXECFLAGS LDLIBWINEFLAGS COREFOUNDATIONLIB IOKITLIB CROSSTEST CROSSCC CROSSWINDRES LDPATH CRTLIBS SOCKETLIBS WINE_BINARIES MAIN_BINARY LDD ALLOCA LIBOBJS LTLIBOBJS'
|
||||
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS WIN16_FILES WIN16_INSTALL DLLDEFS build build_cpu build_vendor build_os host host_cpu host_vendor host_os SET_MAKE CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CXX CXXFLAGS ac_ct_CXX CPPBIN ac_ct_CPPBIN TOOLSDIR CPP X_CFLAGS X_PRE_LIBS X_LIBS X_EXTRA_LIBS LEX LEXLIB LEX_OUTPUT_ROOT XLEX BISON AS ac_ct_AS LD ac_ct_LD AR ac_ct_AR RANLIB ac_ct_RANLIB STRIP ac_ct_STRIP WINDRES ac_ct_WINDRES LN_S LN EGREP LDCONFIG INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LINT LINTFLAGS FONTFORGE LIBPTHREAD XLIB XFILES OPENGLFILES GLU32FILES OPENGL_LIBS GLUT_LIBS GLUT32FILES NASLIBS CURSESLIBS sane_devel SANELIBS SANEINCL ICULIBS ft_devel ft_devel2 FREETYPELIBS FREETYPEINCL FONTSSUBDIRS ARTSCCONFIG ARTSLIBS ARTSINCL ALSALIBS AUDIOIOLIBS EXTRACFLAGS DLLEXT DLLFLAGS DLLIBS LDSHARED LDDLLFLAGS LIBEXT IMPLIBEXT DLLTOOL ac_ct_DLLTOOL DLLWRAP ac_ct_DLLWRAP LDEXECFLAGS LDLIBWINEFLAGS COREFOUNDATIONLIB IOKITLIB CROSSTEST CROSSCC CROSSWINDRES LDPATH CRTLIBS SOCKETLIBS WINE_BINARIES MAIN_BINARY LDD ALLOCA LIBOBJS LTLIBOBJS'
|
||||
ac_subst_files='MAKE_RULES MAKE_DLL_RULES MAKE_TEST_RULES MAKE_LIB_RULES MAKE_PROG_RULES'
|
||||
|
||||
# Initialize some variables set by options.
|
||||
|
@ -5590,170 +5590,6 @@ then
|
|||
|
||||
|
||||
|
||||
for ac_prog in docbook2html db2html
|
||||
do
|
||||
# Extract the first word of "$ac_prog", so it can be a program name with args.
|
||||
set dummy $ac_prog; ac_word=$2
|
||||
echo "$as_me:$LINENO: checking for $ac_word" >&5
|
||||
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
|
||||
if test "${ac_cv_prog_DB2HTML+set}" = set; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
if test -n "$DB2HTML"; then
|
||||
ac_cv_prog_DB2HTML="$DB2HTML" # Let the user override the test.
|
||||
else
|
||||
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
|
||||
for as_dir in $PATH
|
||||
do
|
||||
IFS=$as_save_IFS
|
||||
test -z "$as_dir" && as_dir=.
|
||||
for ac_exec_ext in '' $ac_executable_extensions; do
|
||||
if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
|
||||
ac_cv_prog_DB2HTML="$ac_prog"
|
||||
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
fi
|
||||
fi
|
||||
DB2HTML=$ac_cv_prog_DB2HTML
|
||||
if test -n "$DB2HTML"; then
|
||||
echo "$as_me:$LINENO: result: $DB2HTML" >&5
|
||||
echo "${ECHO_T}$DB2HTML" >&6
|
||||
else
|
||||
echo "$as_me:$LINENO: result: no" >&5
|
||||
echo "${ECHO_T}no" >&6
|
||||
fi
|
||||
|
||||
test -n "$DB2HTML" && break
|
||||
done
|
||||
test -n "$DB2HTML" || DB2HTML="false"
|
||||
|
||||
for ac_prog in docbook2pdf db2pdf
|
||||
do
|
||||
# Extract the first word of "$ac_prog", so it can be a program name with args.
|
||||
set dummy $ac_prog; ac_word=$2
|
||||
echo "$as_me:$LINENO: checking for $ac_word" >&5
|
||||
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
|
||||
if test "${ac_cv_prog_DB2PDF+set}" = set; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
if test -n "$DB2PDF"; then
|
||||
ac_cv_prog_DB2PDF="$DB2PDF" # Let the user override the test.
|
||||
else
|
||||
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
|
||||
for as_dir in $PATH
|
||||
do
|
||||
IFS=$as_save_IFS
|
||||
test -z "$as_dir" && as_dir=.
|
||||
for ac_exec_ext in '' $ac_executable_extensions; do
|
||||
if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
|
||||
ac_cv_prog_DB2PDF="$ac_prog"
|
||||
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
fi
|
||||
fi
|
||||
DB2PDF=$ac_cv_prog_DB2PDF
|
||||
if test -n "$DB2PDF"; then
|
||||
echo "$as_me:$LINENO: result: $DB2PDF" >&5
|
||||
echo "${ECHO_T}$DB2PDF" >&6
|
||||
else
|
||||
echo "$as_me:$LINENO: result: no" >&5
|
||||
echo "${ECHO_T}no" >&6
|
||||
fi
|
||||
|
||||
test -n "$DB2PDF" && break
|
||||
done
|
||||
test -n "$DB2PDF" || DB2PDF="false"
|
||||
|
||||
for ac_prog in docbook2ps db2ps
|
||||
do
|
||||
# Extract the first word of "$ac_prog", so it can be a program name with args.
|
||||
set dummy $ac_prog; ac_word=$2
|
||||
echo "$as_me:$LINENO: checking for $ac_word" >&5
|
||||
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
|
||||
if test "${ac_cv_prog_DB2PS+set}" = set; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
if test -n "$DB2PS"; then
|
||||
ac_cv_prog_DB2PS="$DB2PS" # Let the user override the test.
|
||||
else
|
||||
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
|
||||
for as_dir in $PATH
|
||||
do
|
||||
IFS=$as_save_IFS
|
||||
test -z "$as_dir" && as_dir=.
|
||||
for ac_exec_ext in '' $ac_executable_extensions; do
|
||||
if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
|
||||
ac_cv_prog_DB2PS="$ac_prog"
|
||||
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
fi
|
||||
fi
|
||||
DB2PS=$ac_cv_prog_DB2PS
|
||||
if test -n "$DB2PS"; then
|
||||
echo "$as_me:$LINENO: result: $DB2PS" >&5
|
||||
echo "${ECHO_T}$DB2PS" >&6
|
||||
else
|
||||
echo "$as_me:$LINENO: result: no" >&5
|
||||
echo "${ECHO_T}no" >&6
|
||||
fi
|
||||
|
||||
test -n "$DB2PS" && break
|
||||
done
|
||||
test -n "$DB2PS" || DB2PS="false"
|
||||
|
||||
for ac_prog in docbook2txt db2txt
|
||||
do
|
||||
# Extract the first word of "$ac_prog", so it can be a program name with args.
|
||||
set dummy $ac_prog; ac_word=$2
|
||||
echo "$as_me:$LINENO: checking for $ac_word" >&5
|
||||
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
|
||||
if test "${ac_cv_prog_DB2TXT+set}" = set; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
if test -n "$DB2TXT"; then
|
||||
ac_cv_prog_DB2TXT="$DB2TXT" # Let the user override the test.
|
||||
else
|
||||
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
|
||||
for as_dir in $PATH
|
||||
do
|
||||
IFS=$as_save_IFS
|
||||
test -z "$as_dir" && as_dir=.
|
||||
for ac_exec_ext in '' $ac_executable_extensions; do
|
||||
if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
|
||||
ac_cv_prog_DB2TXT="$ac_prog"
|
||||
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
fi
|
||||
fi
|
||||
DB2TXT=$ac_cv_prog_DB2TXT
|
||||
if test -n "$DB2TXT"; then
|
||||
echo "$as_me:$LINENO: result: $DB2TXT" >&5
|
||||
echo "${ECHO_T}$DB2TXT" >&6
|
||||
else
|
||||
echo "$as_me:$LINENO: result: no" >&5
|
||||
echo "${ECHO_T}no" >&6
|
||||
fi
|
||||
|
||||
test -n "$DB2TXT" && break
|
||||
done
|
||||
test -n "$DB2TXT" || DB2TXT="false"
|
||||
|
||||
for ac_prog in fontforge
|
||||
do
|
||||
# Extract the first word of "$ac_prog", so it can be a program name with args.
|
||||
|
@ -21068,10 +20904,6 @@ s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t
|
|||
s,@INSTALL_DATA@,$INSTALL_DATA,;t t
|
||||
s,@LINT@,$LINT,;t t
|
||||
s,@LINTFLAGS@,$LINTFLAGS,;t t
|
||||
s,@DB2HTML@,$DB2HTML,;t t
|
||||
s,@DB2PDF@,$DB2PDF,;t t
|
||||
s,@DB2PS@,$DB2PS,;t t
|
||||
s,@DB2TXT@,$DB2TXT,;t t
|
||||
s,@FONTFORGE@,$FONTFORGE,;t t
|
||||
s,@LIBPTHREAD@,$LIBPTHREAD,;t t
|
||||
s,@XLIB@,$XLIB,;t t
|
||||
|
|
|
@ -123,10 +123,6 @@ AC_SUBST(LINT)
|
|||
AC_SUBST(LINTFLAGS)
|
||||
|
||||
dnl Check for various programs
|
||||
AC_CHECK_PROGS(DB2HTML, docbook2html db2html, false)
|
||||
AC_CHECK_PROGS(DB2PDF, docbook2pdf db2pdf, false)
|
||||
AC_CHECK_PROGS(DB2PS, docbook2ps db2ps, false)
|
||||
AC_CHECK_PROGS(DB2TXT, docbook2txt db2txt, false)
|
||||
AC_CHECK_PROGS(FONTFORGE, fontforge, false)
|
||||
|
||||
dnl **** Check for some libraries ****
|
||||
|
|
|
@ -1,23 +1,2 @@
|
|||
*.aux
|
||||
*.dvi
|
||||
*.junk
|
||||
*.log
|
||||
*.out
|
||||
*.tex
|
||||
DBTOHTML_OUTPUT_DIR*
|
||||
Makefile
|
||||
wine-devel.html
|
||||
wine-devel.pdf
|
||||
wine-devel.ps
|
||||
wine-devel.txt
|
||||
wine-faq.html
|
||||
wine-faq.txt
|
||||
wine-user.html
|
||||
wine-user.pdf
|
||||
wine-user.ps
|
||||
wine-user.txt
|
||||
wine.man
|
||||
winelib-user.html
|
||||
winelib-user.pdf
|
||||
winelib-user.ps
|
||||
winelib-user.txt
|
||||
|
|
|
@ -3,110 +3,18 @@ TOPOBJDIR = ..
|
|||
SRCDIR = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
MODULE = none
|
||||
DB2HTML = @DB2HTML@
|
||||
DB2PDF = @DB2PDF@
|
||||
DB2PS = @DB2PS@
|
||||
DB2TXT = @DB2TXT@
|
||||
|
||||
EXTRASUBDIRS = samples
|
||||
|
||||
WINE_USER_SRCS = \
|
||||
bugs.sgml \
|
||||
configuring.sgml \
|
||||
fonts.sgml \
|
||||
getting.sgml \
|
||||
glossary.sgml \
|
||||
introduction.sgml \
|
||||
printing.sgml \
|
||||
registry.sgml \
|
||||
running.sgml
|
||||
|
||||
WINE_DEVEL_SRCS = \
|
||||
address-space.sgml \
|
||||
architecture.sgml \
|
||||
ddraw.sgml \
|
||||
debugger.sgml \
|
||||
debugging.sgml \
|
||||
documentation.sgml \
|
||||
multimedia.sgml \
|
||||
ole.sgml \
|
||||
opengl.sgml \
|
||||
patches.sgml \
|
||||
testing.sgml \
|
||||
winedev-coding.sgml \
|
||||
winedev-graphical.sgml \
|
||||
winedev-kernel.sgml \
|
||||
winedev-otherdebug.sgml \
|
||||
winedev-windowing.sgml
|
||||
|
||||
WINELIB_USER_SRCS = \
|
||||
winelib-bindlls.sgml \
|
||||
winelib-intro.sgml \
|
||||
winelib-mfc.sgml \
|
||||
winelib-porting.sgml \
|
||||
winelib-toolkit.sgml
|
||||
|
||||
WINE_FAQ_SRCS = \
|
||||
faq.sgml
|
||||
|
||||
MAN_TARGETS = wine.man
|
||||
|
||||
ALLBOOKS = \
|
||||
wine-devel \
|
||||
wine-user \
|
||||
winelib-user
|
||||
|
||||
all: $(MAN_TARGETS)
|
||||
|
||||
@MAKE_RULES@
|
||||
|
||||
everything: $(MAN_TARGETS) doc
|
||||
doc: html pdf ps txt
|
||||
html: $(ALLBOOKS:%=%.html) wine-faq.html
|
||||
pdf: $(ALLBOOKS:%=%.pdf)
|
||||
ps: $(ALLBOOKS:%=%.ps)
|
||||
txt: $(ALLBOOKS:%=%.txt)
|
||||
|
||||
.PHONY: everything doc html pdf ps dist
|
||||
|
||||
.SUFFIXES: .sgml .html .pdf .ps .txt
|
||||
|
||||
.sgml.html:
|
||||
$(DB2HTML) -u $<
|
||||
|
||||
.sgml.pdf:
|
||||
$(DB2PDF) $<
|
||||
|
||||
.sgml.ps:
|
||||
$(DB2PS) $<
|
||||
|
||||
.sgml.txt:
|
||||
$(DB2TXT) $<
|
||||
|
||||
wine-devel.pdf wine-devel.ps wine-devel.html wine-devel.txt: $(WINE_DEVEL_SRCS)
|
||||
wine-user.pdf wine-user.ps wine-user.html wine-user.txt: $(WINE_USER_SRCS)
|
||||
wine-faq.pdf wine-faq.ps wine-faq.html wine-faq.txt: $(WINE_FAQ_SRCS)
|
||||
winelib-user.pdf winelib-user.ps winelib-user.html winelib-user.txt: $(WINELIB_USER_SRCS)
|
||||
|
||||
wine.man: wine.man.in
|
||||
sed -e 's,@bindir\@,$(bindir),g' -e 's,@dlldir\@,$(dlldir),g' -e 's,@PACKAGE_STRING\@,@PACKAGE_STRING@,g' $(SRCDIR)/wine.man.in >$@ || ($(RM) $@ && false)
|
||||
|
||||
# Rules for distribution tarballs of formatted docs
|
||||
|
||||
dist: wine-doc-ps.tar.gz wine-doc-pdf.tar.gz wine-doc-html.tar.gz wine-doc-txt.tar.gz wine-faq.txt
|
||||
|
||||
wine-doc-ps.tar.gz: $(ALLBOOKS:%=%.ps)
|
||||
tar cf - $(ALLBOOKS:%=%.ps) | gzip -9 > $@ || ($(RM) $@ && false)
|
||||
|
||||
wine-doc-pdf.tar.gz: $(ALLBOOKS:%=%.pdf)
|
||||
tar cf - $(ALLBOOKS:%=%.pdf) | gzip -9 > $@ || ($(RM) $@ && false)
|
||||
|
||||
wine-doc-html.tar.gz: $(ALLBOOKS:%=%.html)
|
||||
tar cf - $(ALLBOOKS:%=%.html) | gzip -9 > $@ || ($(RM) $@ && false)
|
||||
|
||||
wine-doc-txt.tar.gz: $(ALLBOOKS:%=%.txt)
|
||||
tar cf - $(ALLBOOKS:%=%.txt) | gzip -9 > $@ || ($(RM) $@ && false)
|
||||
|
||||
install:: $(MAN_TARGETS)
|
||||
$(MKINSTALLDIRS) $(mandir)/man$(prog_manext) $(mandir)/man$(conf_manext) $(mandir)/man$(api_manext)
|
||||
$(INSTALL_DATA) wine.man $(mandir)/man$(prog_manext)/wine.$(prog_manext)
|
||||
|
@ -120,8 +28,7 @@ install-api-man::
|
|||
for i in $(SRCDIR)/man$(api_manext)/*; do $(INSTALL_DATA) $$i $(mandir)/man$(api_manext); done
|
||||
|
||||
clean::
|
||||
$(RM) *.aux *.dvi *.out *.tex *.log wine-doc-*.tar.gz wine-faq.html wine-faq.txt $(MAN_TARGETS)
|
||||
$(RM) $(ALLBOOKS:%=%.ps) $(ALLBOOKS:%=%.pdf) $(ALLBOOKS:%=%.html) $(ALLBOOKS:%=%.txt)
|
||||
$(RM) -r html api-guide man$(api_manext) *.junk DBTOHTML_OUTPUT_DIR*
|
||||
$(RM) $(MAN_TARGETS)
|
||||
$(RM) -r html api-guide man$(api_manext)
|
||||
|
||||
### Dependencies:
|
||||
|
|
|
@ -1,91 +0,0 @@
|
|||
<chapter id="address-space">
|
||||
<title> Address space management </title>
|
||||
|
||||
<para>
|
||||
A good understanding of memory layout in Unix and Windows is
|
||||
required before reading the next section (<xref
|
||||
linkend="arch-mem"> gives some basic insight).
|
||||
</para>
|
||||
|
||||
<sect1>
|
||||
<title> Laying out the address space </title>
|
||||
|
||||
<para>
|
||||
Up until about the start of 2004, the Linux address space very much resembled the Windows 9x
|
||||
layout: the kernel sat in the top gigabyte, the bottom pages were unmapped to catch null
|
||||
pointer dereferences, and the rest was free. The kernels mmap algorithm was predictable: it
|
||||
would start by mapping files at low addresses and work up from there.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The development of a series of new low level patches violated many of these assumptions, and
|
||||
resulted in Wine needing to force the Win32 address space layout upon the system. This
|
||||
section looks at why and how this is done.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The exec-shield patch increases security by randomizing the kernels mmap algorithms. Rather
|
||||
than consistently choosing the same addresses given the same sequence of requests, the kernel
|
||||
will now choose randomized addresses. Because the Linux dynamic linker (ld-linux.so.2) loads
|
||||
DSOs into memory by using mmap, this means that DSOs are no longer loaded at predictable
|
||||
addresses, so making it harder to attack software by using buffer overflows. It also attempts
|
||||
to relocate certain binaries into a special low area of memory known as the ASCII armor so
|
||||
making it harder to jump into them when using string based attacks.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Prelink is a technology that enhances startup times by precalculating ELF global offset
|
||||
tables then saving the results inside the native binaries themselves. By grid fitting each
|
||||
DSO into the address space, the dynamic linker does not have to perform as many relocations
|
||||
so allowing applications that heavily rely on dynamic linkage to be loaded into memory much
|
||||
quicker. Complex C++ applications such as Mozilla, OpenOffice and KDE can especially benefit
|
||||
from this technique.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The 4G VM split patch was developed by Ingo Molnar. It gives the Linux kernel its own address
|
||||
space, thereby allowing processes to access the maximum addressable amount of memory on a
|
||||
32-bit machine: 4 gigabytes. It allows people with lots of RAM to fully utilise that in any
|
||||
given process at the cost of performance: the reason behind
|
||||
giving the kernel a part of each processes address space was to avoid the overhead of switching on
|
||||
each syscall.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Each of these changes alter the address space in a way incompatible with Windows. Prelink and
|
||||
exec-shield mean that the libraries Wine uses can be placed at any point in the address
|
||||
space: typically this meant that a library was sitting in the region that the EXE you wanted
|
||||
to run had to be loaded (remember that unlike DLLs, EXE files cannot be moved around in
|
||||
memory). The 4G VM split means that programs could receive pointers to the top gigabyte of
|
||||
address space which some are not prepared for (they may store extra information in the high
|
||||
bits of a pointer, for instance). In particular, in combination with exec-shield this one is
|
||||
especially deadly as it's possible the process heap could be allocated beyond
|
||||
ADDRESS_SPACE_LIMIT which causes Wine initialization to fail.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The solution to these problems is for Wine to reserve particular parts of the address space
|
||||
so that areas that we don't want the system to use will be avoided. We later on
|
||||
(re/de)allocate those areas as needed. One problem is that some of these mappings are put in
|
||||
place automatically by the dynamic linker: for instance any libraries that Wine
|
||||
is linked to (like libc, libwine, libpthread etc) will be mapped into memory before Wine even
|
||||
gets control. In order to solve that, Wine overrides the default ELF initialization sequence
|
||||
at a low level and reserves the needed areas by using direct syscalls into the kernel (ie
|
||||
without linking against any other code to do it) before restarting the standard
|
||||
initialization and letting the dynamic linker continue. This is referred to as the
|
||||
preloader and is found in loader/preloader.c.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Once the usual ELF boot sequence has been completed, some native libraries may well have been
|
||||
mapped above the 3gig limit: however, this doesn't matter as 3G is a Windows limit, not a
|
||||
Linux limit. We still have to prevent the system from allocating anything else above there
|
||||
(like the heap or other DLLs) though so Wine performs a binary search over the upper gig of
|
||||
address space in order to iteratively fill in the holes with MAP_NORESERVE mappings so the
|
||||
address space is allocated but the memory to actually back it is not. This code can be found
|
||||
in libs/wine/mmap.c:reserve_area.
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
|
||||
</chapter>
|
|
@ -1,992 +0,0 @@
|
|||
<chapter id="architecture">
|
||||
<title>Overview</title>
|
||||
<para>Brief overview of Wine's architecture...</para>
|
||||
|
||||
<sect1 id="basic-overview">
|
||||
<title>Wine Overview</title>
|
||||
|
||||
<para>
|
||||
With the fundamental architecture of Wine stabilizing, and
|
||||
people starting to think that we might soon be ready to
|
||||
actually release this thing, it may be time to take a look at
|
||||
how Wine actually works and operates.
|
||||
</para>
|
||||
|
||||
<sect2>
|
||||
<title>Foreword</title>
|
||||
<para>
|
||||
Wine is often used as a recursive acronym, standing for
|
||||
"Wine Is Not an Emulator". Sometimes it is also known to be
|
||||
used for "Windows Emulator". In a way, both meanings are
|
||||
correct, only seen from different perspectives. The first
|
||||
meaning says that Wine is not a virtual machine, it does not
|
||||
emulate a CPU, and you are not supposed to install
|
||||
Windows nor any Windows device drivers on top of it; rather,
|
||||
Wine is an implementation of the Windows API, and can be
|
||||
used as a library to port Windows applications to Unix. The
|
||||
second meaning, obviously, is that to Windows binaries
|
||||
(<filename>.exe</filename> files), Wine does look like
|
||||
Windows, and emulates its behaviour and quirks rather
|
||||
closely.
|
||||
</para>
|
||||
<note>
|
||||
<title>"Emulator"</title>
|
||||
<para>
|
||||
The "Emulator" perspective should not be thought of as if
|
||||
Wine is a typical inefficient emulation layer that means
|
||||
Wine can't be anything but slow - the faithfulness to the
|
||||
badly designed Windows API may of course impose a minor
|
||||
overhead in some cases, but this is both balanced out by
|
||||
the higher efficiency of the Unix platforms Wine runs on,
|
||||
and that other possible abstraction libraries (like Motif,
|
||||
GTK+, CORBA, etc) has a runtime overhead typically
|
||||
comparable to Wine's.
|
||||
</para>
|
||||
</note>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Executables</title>
|
||||
<para>
|
||||
Wine's main task is to run Windows executables under non
|
||||
Windows operating systems. It supports different types of
|
||||
executables:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
DOS executable. Those are even older programs, using
|
||||
the DOS format (either <filename>.com</filename> or
|
||||
<filename>.exe</filename> (the later being also called
|
||||
MZ)).
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Windows NE executable, also called 16 bit. They were
|
||||
the native processes run by Windows 2.x and 3.x. NE
|
||||
stands for New Executable <g>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Windows PE executable. These are programs were
|
||||
introduced in Windows 95 (and became the native
|
||||
formats for all later Windows version), even if 16 bit
|
||||
applications were still supported. PE stands for
|
||||
Portable Executable, in a sense where the format of
|
||||
the executable (as a file) is independent of the CPU
|
||||
(even if the content of the file - the code - is CPU
|
||||
dependent).
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Winelib executable. These are applications, written
|
||||
using the Windows API, but compiled as a Unix
|
||||
executable. Wine provides the tools to create such
|
||||
executables.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
<para>
|
||||
Let's quickly review the main differences for the supported
|
||||
executables:
|
||||
<table>
|
||||
<title>Wine executables</title>
|
||||
<tgroup cols="5" align="left" colsep="1" rowsep="1">
|
||||
<thead>
|
||||
<row>
|
||||
<entry></entry>
|
||||
<entry>DOS (.COM or .EXE)</entry>
|
||||
<entry>Win16 (NE)</entry>
|
||||
<entry>Win32 (PE)</entry>
|
||||
<entry>Winelib</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>Multitasking</entry>
|
||||
<entry>Only one application at a time (except for TSR)</entry>
|
||||
<entry>Cooperative</entry>
|
||||
<entry>Preemptive</entry>
|
||||
<entry>Preemptive</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>Address space</entry>
|
||||
<entry>
|
||||
One MB of memory, where each application is loaded
|
||||
and unloaded.
|
||||
</entry>
|
||||
<entry>
|
||||
All 16 bit applications share a single address
|
||||
space, protected mode.
|
||||
</entry>
|
||||
<entry>
|
||||
Each application has it's own address
|
||||
space. Requires MMU support from CPU.
|
||||
</entry>
|
||||
<entry>
|
||||
Each application has it's own address
|
||||
space. Requires MMU support from CPU.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>Windows API</entry>
|
||||
<entry>
|
||||
No Windows API but the DOS API (like <function>Int
|
||||
21h</function> traps).
|
||||
</entry>
|
||||
<entry>
|
||||
Will call the 16 bit Windows API.
|
||||
</entry>
|
||||
<entry>
|
||||
Will call the 32 bit Windows API.
|
||||
</entry>
|
||||
<entry>
|
||||
Will call the 32 bit Windows API, and possibly
|
||||
also the Unix APIs.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>Code (CPU level)</entry>
|
||||
<entry>
|
||||
Only available on x86 in real mode. Code and data
|
||||
are in segmented forms, with 16 bit
|
||||
offsets. Processor is in real mode.
|
||||
</entry>
|
||||
<entry>
|
||||
Only available on IA-32 architectures, code and
|
||||
data are in segmented forms, with 16 bit offsets
|
||||
(hence the 16 bit name). Processor is in protected
|
||||
mode.
|
||||
</entry>
|
||||
<entry>
|
||||
Available (with NT) on several CPUs, including
|
||||
IA-32. On this CPU, uses a flat memory model with
|
||||
32 bit offsets (hence the 32 bit name).
|
||||
</entry>
|
||||
<entry>
|
||||
Flat model, with 32 bit addresses.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>Multi-threading</entry>
|
||||
<entry>Not available.</entry>
|
||||
<entry>Not available.</entry>
|
||||
<entry>
|
||||
Available.
|
||||
</entry>
|
||||
<entry>
|
||||
Available, but must use the Win32 APIs for
|
||||
threading and synchronization, not the Unix ones.
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Wine deals with this issue by launching a separate Wine process (which
|
||||
is in fact a Unix process) for each Win32 process, but not for Win16
|
||||
tasks. Win16 tasks are run as different intersynchronized Unix-threads
|
||||
in the same dedicated Wine process; this Wine process is commonly
|
||||
known as a <firstterm>WOW</firstterm> process (Windows on Windows),
|
||||
referring to a similar mechanism used by Windows NT.
|
||||
</para>
|
||||
<para>
|
||||
Synchronization between the Win16 tasks running in the WOW
|
||||
process is normally done through the Win16 mutex - whenever
|
||||
one of them is running, it holds the Win16 mutex, keeping
|
||||
the others from running. When the task wishes to let the
|
||||
other tasks run, the thread releases the Win16 mutex, and
|
||||
one of the waiting threads will then acquire it and let its
|
||||
task run.
|
||||
</para>
|
||||
<para>
|
||||
<command>winevdm</command> is the Wine process dedicated to running the
|
||||
Win16 processes. Note that several instances of this process could
|
||||
exist, has Windows has support for different VDM (Virtual Dos
|
||||
Machines) in order to have Win16 processes running in different
|
||||
address spaces. Wine also uses the same architecture to run DOS
|
||||
programs (in this case, the DOS emulation is provided by a Wine only
|
||||
DLL called <filename>winedos</filename>.
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Standard Windows Architectures</title>
|
||||
|
||||
<sect2>
|
||||
<title>Windows 9x architecture</title>
|
||||
|
||||
<para>
|
||||
The windows architecture (Win 9x way) looks like this:
|
||||
<screen>
|
||||
+---------------------+ \
|
||||
| Windows EXE | } application
|
||||
+---------------------+ /
|
||||
|
||||
+---------+ +---------+ \
|
||||
| Windows | | Windows | \ application & system DLLs
|
||||
| DLL | | DLL | /
|
||||
+---------+ +---------+ /
|
||||
|
||||
+---------+ +---------+ \
|
||||
| GDI32 | | USER32 | \
|
||||
| DLL | | DLL | \
|
||||
+---------+ +---------+ } core system DLLs
|
||||
+---------------------+ /
|
||||
| Kernel32 DLL | /
|
||||
+---------------------+ /
|
||||
|
||||
+---------------------+ \
|
||||
| Win9x kernel | } kernel space
|
||||
+---------------------+ /
|
||||
|
||||
+---------------------+ \
|
||||
| Windows low-level | \ drivers (kernel space)
|
||||
| drivers | /
|
||||
+---------------------+ /
|
||||
</screen>
|
||||
</para>
|
||||
</sect2>
|
||||
<sect2>
|
||||
<title>Windows NT architecture</title>
|
||||
|
||||
<para>
|
||||
The windows architecture (Windows NT way) looks like the
|
||||
following drawing. Note the new DLL
|
||||
(<filename>NTDLL</filename>) which allows implementing
|
||||
different subsystems (as win32);
|
||||
<filename>kernel32</filename> in NT architecture
|
||||
implements the Win32 subsystem on top of
|
||||
<filename>NTDLL</filename>.
|
||||
<screen>
|
||||
+---------------------+ \
|
||||
| Windows EXE | } application
|
||||
+---------------------+ /
|
||||
|
||||
+---------+ +---------+ \
|
||||
| Windows | | Windows | \ application & system DLLs
|
||||
| DLL | | DLL | /
|
||||
+---------+ +---------+ /
|
||||
|
||||
+---------+ +---------+ +-----------+ \
|
||||
| GDI32 | | USER32 | | | \
|
||||
| DLL | | DLL | | | \
|
||||
+---------+ +---------+ | | \ core system DLLs
|
||||
+---------------------+ | | / (on the left side)
|
||||
| Kernel32 DLL | | Subsystem | /
|
||||
| (Win32 subsystem) | |Posix, OS/2| /
|
||||
+---------------------+ +-----------+ /
|
||||
|
||||
+---------------------------------------+
|
||||
| NTDLL.DLL |
|
||||
+---------------------------------------+
|
||||
|
||||
+---------------------------------------+ \
|
||||
| NT kernel | } NT kernel (kernel space)
|
||||
+---------------------------------------+ /
|
||||
+---------------------------------------+ \
|
||||
| Windows low-level drivers | } drivers (kernel space)
|
||||
+---------------------------------------+ /
|
||||
</screen>
|
||||
</para>
|
||||
<para>
|
||||
Note also (not depicted in schema above) that the 16 bit
|
||||
applications are supported in a specific subsystem.
|
||||
Some basic differences between the Win9x and the NT
|
||||
architectures include:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
Several subsystems (Win32, Posix...) can be run on NT,
|
||||
while not on Win 9x
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Win 9x roots its architecture in 16 bit systems, while
|
||||
NT is truly a 32 bit system.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The drivers model and interfaces in Win 9x and NT are
|
||||
different (even if Microsoft tried to bridge the gap
|
||||
with some support of WDM drivers in Win 98 and above).
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Wine architecture</title>
|
||||
|
||||
<sect2>
|
||||
<title>Global picture</title>
|
||||
|
||||
<para>
|
||||
Wine implementation is closer to the Windows NT
|
||||
architecture, even if several subsystems are not implemented
|
||||
yet (remind also that 16bit support is implemented in a 32-bit
|
||||
Windows EXE, not as a subsystem). Here's the overall picture:
|
||||
<screen>
|
||||
+---------------------+ \
|
||||
| Windows EXE | } application
|
||||
+---------------------+ /
|
||||
|
||||
+---------+ +---------+ \
|
||||
| Windows | | Windows | \ application & system DLLs
|
||||
| DLL | | DLL | /
|
||||
+---------+ +---------+ /
|
||||
|
||||
+---------+ +---------+ +-----------+ +--------+ \
|
||||
| GDI32 | | USER32 | | | | | \
|
||||
| DLL | | DLL | | | | Wine | \
|
||||
+---------+ +---------+ | | | Server | \ core system DLLs
|
||||
+---------------------+ | | | | / (on the left side)
|
||||
| Kernel32 DLL | | Subsystem | | NT-like| /
|
||||
| (Win32 subsystem) | |Posix, OS/2| | Kernel | /
|
||||
+---------------------+ +-----------+ | | /
|
||||
| |
|
||||
+---------------------------------------+ | |
|
||||
| NTDLL | | |
|
||||
+---------------------------------------+ +--------+
|
||||
|
||||
+---------------------------------------+ \
|
||||
| Wine executable (wine-?thread) | } unix executable
|
||||
+---------------------------------------+ /
|
||||
+---------------------------------------------------+ \
|
||||
| Wine drivers | } Wine specific DLLs
|
||||
+---------------------------------------------------+ /
|
||||
|
||||
+------------+ +------------+ +--------------+ \
|
||||
| libc | | libX11 | | other libs | } unix shared libraries
|
||||
+------------+ +------------+ +--------------+ / (user space)
|
||||
|
||||
+---------------------------------------------------+ \
|
||||
| Unix kernel (Linux,*BSD,Solaris,OS/X) | } (Unix) kernel space
|
||||
+---------------------------------------------------+ /
|
||||
+---------------------------------------------------+ \
|
||||
| Unix device drivers | } Unix drivers (kernel space)
|
||||
+---------------------------------------------------+ /
|
||||
</screen>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Wine must at least completely replace the "Big Three" DLLs
|
||||
(<filename>KERNEL</filename>/<filename>KERNEL32</filename>,
|
||||
<filename>GDI</filename>/<filename>GDI32</filename>, and
|
||||
<filename>USER</filename>/<filename>USER32</filename>),
|
||||
which all other DLLs are layered on top of. But since Wine
|
||||
is (for various reasons) leaning towards the NT way of
|
||||
implementing things, the <filename>NTDLL</filename> is
|
||||
another core DLL to be implemented in Wine, and many
|
||||
<filename>KERNEL32</filename> and
|
||||
<filename>ADVAPI32</filename> features will be
|
||||
implemented through the <filename>NTDLL</filename>.
|
||||
</para>
|
||||
<para>
|
||||
As of today, no real subsystem (apart the Win32 one) has
|
||||
been implemented in Wine.
|
||||
</para>
|
||||
<para>
|
||||
The Wine server provides the backbone for the implementation
|
||||
of the core DLLs. It mainly implementents inter-process
|
||||
synchronization and object sharing. It can be seen, from a
|
||||
functional point of view, as a NT kernel (even if the APIs
|
||||
and protocols used between Wine's DLL and the Wine server
|
||||
are Wine specific).
|
||||
</para>
|
||||
<para>
|
||||
Wine uses the Unix drivers to access the various hardware
|
||||
pieces on the box. However, in some cases, Wine will
|
||||
provide a driver (in Windows sense) to a physical hardware
|
||||
device. This driver will be a proxy to the Unix driver
|
||||
(this is the case, for example, for the graphical part
|
||||
with X11 or SDL drivers, audio with OSS or ALSA drivers...).
|
||||
</para>
|
||||
<para>
|
||||
All DLLs provided by Wine try to stick as much as possible
|
||||
to the exported APIs from the Windows platforms. There are
|
||||
rare cases where this is not the case, and have been
|
||||
propertly documented (Wine DLLs export some Wine specific
|
||||
APIs). Usually, those are prefixed with
|
||||
<function>__wine</function>.
|
||||
</para>
|
||||
<para>
|
||||
Let's now review in greater details all of those components.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>The Wine server</title>
|
||||
<para>
|
||||
The Wine server is among the most confusing concepts in
|
||||
Wine. What is its function in Wine? Well, to be brief, it
|
||||
provides Inter-Process Communication (IPC),
|
||||
synchronization, and process/thread management. When the
|
||||
Wine server launches, it creates a Unix socket for the
|
||||
current host based on (see below) your home directory's
|
||||
<filename>.wine</filename> subdirectory (or wherever the
|
||||
<envar>WINEPREFIX</envar> environment variable points to)
|
||||
- all Wine processes launched later connects to the Wine
|
||||
server using this socket. If a Wine server was not
|
||||
already running, the first Wine process will start up the
|
||||
Wine server in auto-terminate mode (i.e. the Wine server
|
||||
will then terminate itself once the last Wine process has
|
||||
terminated).
|
||||
</para>
|
||||
<para>
|
||||
In earlier versions of Wine the master socket mentioned
|
||||
above was actually created in the configuration directory;
|
||||
either your home directory's <filename>/wine</filename>
|
||||
subdirectory or wherever the
|
||||
<envar>WINEPREFIX</envar> environment variable points>.
|
||||
Since that might not be possible the socket is actually
|
||||
created within the <filename>/tmp</filename> directory
|
||||
with a name that reflects the configuration directory.
|
||||
This means that there can actually be several separate
|
||||
copies of the Wine server running; one per combination of
|
||||
user and configuration directory. Note that you should
|
||||
not have several users using the same configuration
|
||||
directory at the same time; they will have different
|
||||
copies of the Wine server running and this could well
|
||||
lead to problems with the registry information that
|
||||
they are sharing.
|
||||
</para>
|
||||
<para>
|
||||
Every thread in each Wine process has its own request
|
||||
buffer, which is shared with the Wine server. When a
|
||||
thread needs to synchronize or communicate with any other
|
||||
thread or process, it fills out its request buffer, then
|
||||
writes a command code through the socket. The Wine server
|
||||
handles the command as appropriate, while the client
|
||||
thread waits for a reply. In some cases, like with the
|
||||
various <function>WaitFor???</function> synchronization
|
||||
primitives, the server handles it by marking the client
|
||||
thread as waiting and does not send it a reply before the
|
||||
wait condition has been satisfied.
|
||||
</para>
|
||||
<para>
|
||||
The Wine server itself is a single and separate Unix
|
||||
process and does not have its own threading - instead, it
|
||||
is built on top of a large <function>poll()</function>
|
||||
loop that alerts the Wine server whenever anything
|
||||
happens, such as a client having sent a command, or a wait
|
||||
condition having been satisfied. There is thus no danger
|
||||
of race conditions inside the Wine server itself - it is
|
||||
often called upon to do operations that look completely
|
||||
atomic to its clients.
|
||||
</para>
|
||||
<para>
|
||||
Because the Wine server needs to manage processes,
|
||||
threads, shared handles, synchronization, and any related
|
||||
issues, all the clients' Win32 objects are also managed by
|
||||
the Wine server, and the clients must send requests to the
|
||||
Wine server whenever they need to know any Win32 object
|
||||
handle's associated Unix file descriptor (in which case
|
||||
the Wine server duplicates the file descriptor, transmits
|
||||
it back to the client, and leaves it to the client to
|
||||
close the duplicate when the client has finished with
|
||||
it).
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>
|
||||
Wine builtin DLLs: about Relays, Thunks, and DLL
|
||||
descriptors
|
||||
</title>
|
||||
<para>
|
||||
This section mainly applies to builtin DLLs (DLLs provided
|
||||
by Wine). See section <xref linkend="arch-dlls"> for the
|
||||
details on native vs. builtin DLL handling.
|
||||
</para>
|
||||
<para>
|
||||
Loading a Windows binary into memory isn't that hard by
|
||||
itself, the hard part is all those various DLLs and entry
|
||||
points it imports and expects to be there and function as
|
||||
expected; this is, obviously, what the entire Wine
|
||||
implementation is all about. Wine contains a range of DLL
|
||||
implementations. You can find the DLLs implementation in the
|
||||
<filename>dlls/</filename> directory.
|
||||
</para>
|
||||
<para>
|
||||
Each DLL (at least, the 32 bit version, see below) is
|
||||
implemented in a Unix shared library. The file name of this
|
||||
shared library is the module name of the DLL with a
|
||||
<filename>.dll.so</filename> suffix (or
|
||||
<filename>.drv.so</filename> or any other relevant extension
|
||||
depending on the DLL type). This shared library contains the
|
||||
code itself for the DLL, as well as some more information,
|
||||
as the DLL resources and a Wine specific DLL descriptor.
|
||||
</para>
|
||||
<para>
|
||||
The DLL descriptor, when the DLL is instanciated, is used to
|
||||
create an in-memory PE header, which will provide access to
|
||||
various information about the DLL, including but not limited
|
||||
to its entry point, its resources, its sections, its debug
|
||||
information...
|
||||
</para>
|
||||
<para>
|
||||
The DLL descriptor and entry point table is generated by
|
||||
the <command>winebuild</command> tool (previously just
|
||||
named <command>build</command>), taking DLL specification
|
||||
files with the extension <filename>.spec</filename> as
|
||||
input. Resources (after compilation by
|
||||
<command>wrc</command>) or message tables (after
|
||||
compilation by <command>wmc</command>) are also added to
|
||||
the descriptor by <command>winebuild</command>.
|
||||
</para>
|
||||
<para>
|
||||
Once an application module wants to import a DLL, Wine
|
||||
will look at:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
through its list of registered DLLs (in fact, both
|
||||
the already loaded DLLs, and the already loaded
|
||||
shared libraries which has registered a DLL
|
||||
descriptor). Since, the DLL descriptor is
|
||||
automatically registered when the shared library is
|
||||
loaded - remember, registration call is put inside a
|
||||
shared library constructor - using the
|
||||
<envar>PRELOAD</envar> environment variable when
|
||||
running a Wine process can force the registration of
|
||||
some DLL descriptors.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
If it's not registered, Wine will look for it on
|
||||
disk, building the shared library name from the DLL
|
||||
module name. Directory searched for are specified by
|
||||
the <envar>WINEDLLPATH</envar> environment variable.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Failing that, it will look for a real Windows
|
||||
<filename>.DLL</filename> file to use, and look
|
||||
through its imports, etc) and use the loading of
|
||||
native DLLs.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
<para>
|
||||
After the DLL has been identified (assuming it's still a
|
||||
native one), it's mapped into memory using a
|
||||
<function>dlopen()</function> call. Note, that Wine doesn't
|
||||
use the shared library mechanisms for resolving and/or
|
||||
importing functions between two shared libraries (for two
|
||||
DLLs). The shared library is only used for providing a way
|
||||
to load a piece of code on demand. This piece of code,
|
||||
thanks the DLL descriptor, will provide the same type of
|
||||
information a native DLL would. Wine can then use the same
|
||||
code for native and builtin DLL to handle imports/exports.
|
||||
</para>
|
||||
<para>
|
||||
Wine also relies on the dynamic loading features of the Unix
|
||||
shared libraries to relocate the DLLs if needed (the same
|
||||
DLL can be loaded at different address in two different
|
||||
processes, and even in two consecutive run of the same
|
||||
executable if the order of loading the DLLs differ).
|
||||
</para>
|
||||
<para>
|
||||
The DLL descriptor is registered in the Wine realm using
|
||||
some tricks. The <command>winebuild</command> tool, while
|
||||
creating the code for DLL descriptor, also creates a
|
||||
constructor, that will be called when the shared library is
|
||||
loaded into memory. This constructor will actually register
|
||||
the descriptor to the Wine DLL loader. Hence, before the
|
||||
<function>dlopen</function> call returns, the DLL descriptor
|
||||
will be known and registered. This also helps to deal with
|
||||
the cases where there's still dependencies (at the ELF
|
||||
shared lib level, not at the embedded DLL level) between
|
||||
different shared libraries: the embedded DLLs will be
|
||||
properly registered, and even loaded (from a Windows point
|
||||
of view).
|
||||
</para>
|
||||
<para>
|
||||
Since Wine is 32-bit code itself, and if the compiler
|
||||
supports Windows' calling convention, <type>stdcall</type>
|
||||
(<command>gcc</command> does), Wine can resolve imports
|
||||
into Win32 code by substituting the addresses of the Wine
|
||||
handlers directly without any thunking layer in
|
||||
between. This eliminates the overhead most people
|
||||
associate with "emulation", and is what the applications
|
||||
expect anyway.
|
||||
</para>
|
||||
<para>
|
||||
However, if the user specified <parameter>WINEDEBUG=+relay
|
||||
</parameter>, a thunk layer is inserted between the
|
||||
application imports and the Wine handlers (actually the
|
||||
export table of the DLL is modified, and a thunk is
|
||||
inserted in the table); this layer is known as "relay"
|
||||
because all it does is print out the arguments/return
|
||||
values (by using the argument lists in the DLL
|
||||
descriptor's entry point table), then pass the call on,
|
||||
but it's invaluable for debugging misbehaving calls into
|
||||
Wine code. A similar mechanism also exists between Windows
|
||||
DLLs - Wine can optionally insert thunk layers between
|
||||
them, by using <parameter>WINEDEBUG=+snoop</parameter>,
|
||||
but since no DLL descriptor information exists for
|
||||
non-Wine DLLs, this is less reliable and may lead to
|
||||
crashes.
|
||||
</para>
|
||||
<para>
|
||||
For Win16 code, there is no way around thunking - Wine
|
||||
needs to relay between 16-bit and 32-bit code. These
|
||||
thunks switch between the app's 16-bit stack and Wine's
|
||||
32-bit stack, copies and converts arguments as appropriate
|
||||
(an int is 16 bit 16-bit and 32 bits in 32-bit, pointers
|
||||
are segmented in 16 bit (and also near or far) but are 32
|
||||
bit linear values in 32 bit), and handles the Win16
|
||||
mutex. Some finer control can be obtained on the
|
||||
conversion, see <command>winebuild</command> reference
|
||||
manual for the details. Suffice to say that the kind of
|
||||
intricate stack content juggling this results in, is not
|
||||
exactly suitable study material for beginners.
|
||||
</para>
|
||||
<para>
|
||||
A DLL descriptor is also created for every 16 bit
|
||||
DLL. However, this DLL normally paired with a 32 bit
|
||||
DLL. Either, it's the 16 bit counterpart of the 16 bit DLL
|
||||
(<filename>KRNL386.EXE</filename> for
|
||||
<filename>KERNEL32</filename>, <filename>USER</filename>
|
||||
for <filename>USER32</filename>...), or a 16
|
||||
bit DLL directly linked to a 32 bit DLL (like
|
||||
<filename>SYSTEM</filename> for <filename>KERNEL32</filename>,
|
||||
or <filename>DDEML</filename> for
|
||||
<filename>USER32</filename>). In those cases, the 16 bit
|
||||
descriptor(s) is (are) inserted in the same shared library
|
||||
as the the corresponding 32 bit DLL. Wine will also create
|
||||
symbolic links between kernel32.dll.so and system.dll.so
|
||||
so that loading of either
|
||||
<filename>KERNEL32.DLL</filename> or
|
||||
<filename>SYSTEM.DLL</filename> will end up on the same
|
||||
shared library.
|
||||
</para>
|
||||
</sect2>
|
||||
<sect2 id="arch-dlls">
|
||||
<title>Wine/Windows DLLs</title>
|
||||
|
||||
<para>
|
||||
This document mainly deals with the status of current DLL
|
||||
support by Wine. The Wine ini file currently supports
|
||||
settings to change the load order of DLLs. The load order
|
||||
depends on several issues, which results in different settings
|
||||
for various DLLs.
|
||||
</para>
|
||||
|
||||
<sect3>
|
||||
<title>Pros of Native DLLs</title>
|
||||
|
||||
<para>
|
||||
Native DLLs of course guarantee 100% compatibility for
|
||||
routines they implement. For example, using the native
|
||||
<filename>USER</filename> DLL would maintain a virtually
|
||||
perfect and Windows 95-like look for window borders,
|
||||
dialog controls, and so on. Using the built-in Wine
|
||||
version of this library, on the other hand, would produce
|
||||
a display that does not precisely mimic that of Windows
|
||||
95. Such subtle differences can be engendered in other
|
||||
important DLLs, such as the common controls library
|
||||
<filename>COMMCTRL</filename> or the common dialogs library
|
||||
<filename>COMMDLG</filename>, when built-in Wine DLLs
|
||||
outrank other types in load order.
|
||||
</para>
|
||||
<para>
|
||||
More significant, less aesthetically-oriented problems can
|
||||
result if the built-in Wine version of the
|
||||
<filename>SHELL</filename> DLL is loaded before the native
|
||||
version of this library. <filename>SHELL</filename>
|
||||
contains routines such as those used by installer utilities
|
||||
to create desktop shortcuts. Some installers might fail when
|
||||
using Wine's built-in <filename>SHELL</filename>.
|
||||
</para>
|
||||
</sect3>
|
||||
|
||||
<sect3>
|
||||
<title>Cons of Native DLLs</title>
|
||||
|
||||
<para>
|
||||
Not every application performs better under native DLLs. If
|
||||
a library tries to access features of the rest of the system
|
||||
that are not fully implemented in Wine, the native DLL might
|
||||
work much worse than the corresponding built-in one, if at
|
||||
all. For example, the native Windows <filename>GDI</filename>
|
||||
library must be paired with a Windows display driver, which
|
||||
of course is not present under Intel Unix and Wine.
|
||||
</para>
|
||||
<para>
|
||||
Finally, occasionally built-in Wine DLLs implement more
|
||||
features than the corresponding native Windows DLLs.
|
||||
Probably the most important example of such behavior is the
|
||||
integration of Wine with X provided by Wine's built-in
|
||||
<filename>USER</filename> DLL. Should the native Windows
|
||||
<filename>USER</filename> library take load-order
|
||||
precedence, such features as the ability to use the
|
||||
clipboard or drag-and-drop between Wine windows and X
|
||||
windows will be lost.
|
||||
</para>
|
||||
</sect3>
|
||||
|
||||
<sect3>
|
||||
<title>Deciding Between Native and Built-In DLLs</title>
|
||||
|
||||
<para>
|
||||
Clearly, there is no one rule-of-thumb regarding which
|
||||
load-order to use. So, you must become familiar with
|
||||
what specific DLLs do and which other DLLs or features
|
||||
a given library interacts with, and use this information
|
||||
to make a case-by-case decision.
|
||||
</para>
|
||||
</sect3>
|
||||
|
||||
<sect3>
|
||||
<title>Load Order for DLLs</title>
|
||||
|
||||
<para>
|
||||
Using the DLL sections from the wine configuration file, the
|
||||
load order can be tweaked to a high degree. In general it is
|
||||
advised not to change the settings of the configuration
|
||||
file. The default configuration specifies the right load
|
||||
order for the most important DLLs.
|
||||
</para>
|
||||
<para>
|
||||
The default load order follows this algorithm: for all DLLs
|
||||
which have a fully-functional Wine implementation, or where
|
||||
the native DLL is known not to work, the built-in library
|
||||
will be loaded first. In all other cases, the native DLL
|
||||
takes load-order precedence.
|
||||
</para>
|
||||
<para>
|
||||
The <varname>DefaultLoadOrder</varname> from the
|
||||
[DllDefaults] section specifies for all DLLs which version
|
||||
to try first. See manpage for explanation of the arguments.
|
||||
</para>
|
||||
<para>
|
||||
The [DllOverrides] section deals with DLLs, which need a
|
||||
different-from-default treatment.
|
||||
</para>
|
||||
<para>
|
||||
The [DllPairs] section is for DLLs, which must be loaded in
|
||||
pairs. In general, these are DLLs for either 16-bit or
|
||||
32-bit applications. In most cases in Windows, the 32-bit
|
||||
version cannot be used without its 16-bit counterpart. For
|
||||
Wine, it is customary that the 16-bit implementations rely
|
||||
on the 32-bit implementations and cast the results back to
|
||||
16-bit arguments. Changing anything in this section is bound
|
||||
to result in errors.
|
||||
</para>
|
||||
<para>
|
||||
For the future, the Wine implementation of Windows DLL seems
|
||||
to head towards unifying the 16 and 32 bit DLLs wherever
|
||||
possible, resulting in larger DLLs. They are stored in the
|
||||
<filename>dlls/</filename> subdirectory using the 32-bit
|
||||
name.
|
||||
</para>
|
||||
</sect3>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="arch-mem">
|
||||
<title>Memory management</title>
|
||||
<para>
|
||||
Every Win32 process in Wine has its own dedicated native
|
||||
process on the host system, and therefore its own address
|
||||
space. This section explores the layout of the Windows
|
||||
address space and how it is emulated.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Firstly, a quick recap of how virtual memory works. Physical
|
||||
memory in RAM chips is split into
|
||||
<emphasis>frames</emphasis>, and the memory that each
|
||||
process sees is split into <emphasis>pages</emphasis>. Each
|
||||
process has its own 4 gigabytes of address space (4gig being
|
||||
the maximum space addressable with a 32 bit pointer). Pages
|
||||
can be mapped or unmapped: attempts to access an unmapped
|
||||
page cause an
|
||||
<constant>EXCEPTION_ACCESS_VIOLATION</constant> which has
|
||||
the easily recognizable code of
|
||||
<constant>0xC0000005</constant>. Any page can be mapped to
|
||||
any frame, therefore you can have multiple addresses which
|
||||
actually "contain" the same memory. Pages can also be mapped
|
||||
to things like files or swap space, in which case accessing
|
||||
that page will cause a disk access to read the contents into
|
||||
a free frame.
|
||||
</para>
|
||||
|
||||
<sect3>
|
||||
<title>Initial layout (in Windows)</title>
|
||||
<para>
|
||||
When a Win32 process starts, it does not have a clear
|
||||
address space to use as it pleases. Many pages are already
|
||||
mapped by the operating system. In particular, the EXE
|
||||
file itself and any DLLs it needs are mapped into memory,
|
||||
and space has been reserved for the stack and a couple of
|
||||
heaps (zones used to allocate memory to the app
|
||||
from). Some of these things need to be at a fixed address,
|
||||
and others can be placed anywhere.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The EXE file itself is usually mapped at address
|
||||
<constant>0x400000</constant> and up: indeed, most EXEs have
|
||||
their relocation records stripped which means they must be
|
||||
loaded at their base address and cannot be loaded at any
|
||||
other address.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
DLLs are internally much the same as EXE files but they
|
||||
have relocation records, which means that they can be
|
||||
mapped at any address in the address space. Remember we
|
||||
are not dealing with physical memory here, but rather
|
||||
virtual memory which is different for each
|
||||
process. Therefore <filename>OLEAUT32.DLL</filename> may
|
||||
be loaded at one address in one process, and a totally
|
||||
different one in another. Ensuring all the functions
|
||||
loaded into memory can find each other is the job of the
|
||||
Windows dynamic linker, which is a part of
|
||||
<filename>NTDLL</filename>.
|
||||
</para>
|
||||
<para>
|
||||
So, we have the EXE and its DLLs mapped into memory. Two
|
||||
other very important regions also exist: the stack and the
|
||||
process heap. The process heap is simply the equivalent of
|
||||
the libc <function>malloc</function> arena on UNIX: it's a
|
||||
region of memory managed by the OS which
|
||||
<function>malloc</function>/<function>HeapAlloc</function>
|
||||
partitions and hands out to the application. Windows
|
||||
applications can create several heaps but the process heap
|
||||
always exists.
|
||||
</para>
|
||||
<para>
|
||||
Windows 9x also implements another kind of heap: the
|
||||
shared heap. The shared heap is unusual in that
|
||||
anything allocated from it will be visible in every other
|
||||
process.
|
||||
</para>
|
||||
</sect3>
|
||||
|
||||
<sect3>
|
||||
<title>Comparison</title>
|
||||
<para>
|
||||
So far we've assumed the entire 4 gigs of address space is
|
||||
available for the application. In fact that's not so: only
|
||||
the lower 2 gigs are available, the upper 2 gigs are on
|
||||
Windows NT used by the operating system and hold the
|
||||
kernel (from <constant>0x80000000</constant>). Why is the
|
||||
kernel mapped into every address space? Mostly for
|
||||
performance: while it's possible to give the kernel its own
|
||||
address space too - this is what Ingo Molnars 4G/4G VM
|
||||
split patch does for Linux - it requires that every system
|
||||
call into the kernel switches address space. As that is a
|
||||
fairly expensive operation (requires flushing the
|
||||
translation lookaside buffers etc) and syscalls are made
|
||||
frequently it's best avoided by keeping the kernel mapped
|
||||
at a constant position in every processes address space.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Basically, the comparison of memory mappings looks as
|
||||
follows:
|
||||
<table>
|
||||
<title>Memory layout (Windows and Wine)</title>
|
||||
<tgroup cols="4" align="left" colsep="1" rowsep="1">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Address</entry>
|
||||
<entry>Windows 9x</entry>
|
||||
<entry>Windows NT</entry>
|
||||
<entry>Linux</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>00000000-7fffffff</entry>
|
||||
<entry>User</entry>
|
||||
<entry>User</entry>
|
||||
<entry>User</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>80000000-bfffffff</entry>
|
||||
<entry>Shared</entry>
|
||||
<entry>User</entry>
|
||||
<entry>User</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>c0000000-ffffffff</entry>
|
||||
<entry>Kernel</entry>
|
||||
<entry>Kernel</entry>
|
||||
<entry>Kernel</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
On Windows 9x, in fact only the upper gigabyte
|
||||
(<constant>0xC0000000</constant> and up) is used by the
|
||||
kernel, the region from 2 to 3 gigs is a shared area used
|
||||
for loading system DLLs and for file mappings. The bottom
|
||||
2 gigs on both NT and 9x are available for the programs
|
||||
memory allocation and stack.
|
||||
</para>
|
||||
</sect3>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Wine drivers</title>
|
||||
<para>
|
||||
Wine will not allow running native Windows drivers under
|
||||
Unix. This comes mainly because (look at the generic
|
||||
architecture schemas) Wine doesn't implement the kernel
|
||||
features of Windows (kernel here really means the kernel,
|
||||
not the <filename>KERNEL32</filename> DLL), but rather
|
||||
sets up a proxy layer on top of the Unix kernel to provide
|
||||
the <filename>NTDLL</filename> and
|
||||
<filename>KERNEL32</filename> features. This means that
|
||||
Wine doesn't provide the inner infrastructure to run
|
||||
native drivers, either from the Win9x family or from the
|
||||
NT family.
|
||||
</para>
|
||||
<para>
|
||||
In other words, Wine will only be able to provide access to
|
||||
a specific device, if and only if, 1/ this device is
|
||||
supported in Unix (there is Unix-driver to talk to it), 2/
|
||||
Wine has implemented the proxy code to make the glue between
|
||||
the API of a Windows driver, and the Unix interface of the
|
||||
Unix driver.
|
||||
</para>
|
||||
<para>
|
||||
Wine, however, tries to implement in the various DLLs
|
||||
needing to access devices to do it through the standard
|
||||
Windows APIs for device drivers in user space. This is for
|
||||
example the case for the multimedia drivers, where Wine
|
||||
loads Wine builtin DLLs to talk to the OSS interface, or the
|
||||
ALSA interface. Those DLLs implement the same interface as
|
||||
any user space audio driver in Windows.
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
||||
|
||||
<!-- Keep this comment at the end of the file
|
||||
Local variables:
|
||||
mode: sgml
|
||||
sgml-parent-document:("wine-devel.sgml" "set" "book" "part" "chapter" "")
|
||||
End:
|
||||
-->
|
|
@ -1,499 +0,0 @@
|
|||
<chapter id="bugs">
|
||||
<title>Troubleshooting / Reporting bugs</title>
|
||||
|
||||
<sect1 id="troubleshooting">
|
||||
<title>What to do if some program still doesn't work?</title>
|
||||
|
||||
<para>
|
||||
There are times when you've been trying everything, you even killed a cat
|
||||
at full moon and ate it with rotten garlic and foul fish
|
||||
while doing the Devil's Dance, yet nothing helped to make some damn
|
||||
program work on some Wine version.
|
||||
Don't despair, we're here to help you...
|
||||
(in other words: how much do you want to pay ?)
|
||||
</para>
|
||||
|
||||
<sect2>
|
||||
<title>Verify your wine configuration</title>
|
||||
<para>
|
||||
Refer to the <link linkend="config-verify">Configuration verification section</link>
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Use different windows version settings</title>
|
||||
|
||||
<para>
|
||||
In several cases using <link linkend="config-windows-versions">different windows version settings</link> can help.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Use different startup paths</title>
|
||||
|
||||
<para>
|
||||
This sometimes helps, too:
|
||||
|
||||
Try to use both
|
||||
<command>wine prg.exe</command>
|
||||
and
|
||||
<command>wine x:\\full\\path\\to\\prg.exe</command>
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Fiddle with DLL configuration</title>
|
||||
|
||||
<para>
|
||||
Run with WINEDEBUG=+loaddll to figure out which DLLs are
|
||||
being used, and whether they're being loaded as native or
|
||||
built-in.
|
||||
Then make sure you have proper native DLL files in your
|
||||
configured C:\windows\system directory and fiddle with DLL
|
||||
load order settings at command line or in config file.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Check your system environment !</title>
|
||||
|
||||
<para>
|
||||
Just an idea: could it be that your Wine build/execution
|
||||
environment is broken ?
|
||||
|
||||
Make sure that there are no problems whatsoever with the
|
||||
packages
|
||||
that Wine depends on (gcc, glibc, X libraries, OpenGL (!), ...)
|
||||
|
||||
E.g. some people have strange failures to find stuff when
|
||||
using "wrong" header files for the "right" libraries !!!
|
||||
(which results in days of debugging to desperately try to find
|
||||
out why that lowlevel function fails in a way that is completely
|
||||
beyond imagination... ARGH !)
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Use different GUI (Window Manager) modes</title>
|
||||
|
||||
<para>
|
||||
Instruct Wine via config file to use either desktop mode,
|
||||
managed mode or plain ugly "normal" mode.
|
||||
That can make one hell of a difference, too.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Check your app !</title>
|
||||
|
||||
<para>
|
||||
Maybe your app is using some kind of copy protection ?
|
||||
|
||||
Many copy protections currently don't work on Wine.
|
||||
Some might work in the future, though.
|
||||
(the CD-ROM layer isn't really full-featured yet).
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Go to <ulink
|
||||
url="http://www.gamecopyworld.com">GameCopyWorld</ulink>
|
||||
and try to find a decent crack for your game that gets rid of
|
||||
that ugly copy protection.
|
||||
I hope you do have a legal copy of the program, though... :-)
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Check your Wine environment !</title>
|
||||
|
||||
<para>
|
||||
Running with or without a Windows partition can have a
|
||||
dramatic impact.
|
||||
|
||||
Configure Wine to do the opposite of what you used to have.
|
||||
|
||||
Also, install DCOM98 or DCOM95. This can be very beneficial.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Reconfigure Wine</title>
|
||||
|
||||
<para>
|
||||
Sometimes wine installation process changes and new versions of
|
||||
Wine account on these changes.
|
||||
This is especially true if your setup was created long time ago.
|
||||
|
||||
Rename your existing <filename>~/.wine</filename> directory
|
||||
for backup purposes.
|
||||
Use the setup process that's recommended for your Wine distribution
|
||||
to create new configuration.
|
||||
Use information in old <filename>~/.wine</filename>
|
||||
directory as a reference.
|
||||
For source wine distribution to configure Wine run
|
||||
tools/wineinstall script as a user you want to do the configuration
|
||||
for.
|
||||
This is a pretty safe operation. Later you can remove the new
|
||||
<filename>~/.wine</filename> directory and rename your old one back.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Check out further information</title>
|
||||
|
||||
<para>
|
||||
There is a really good chance that someone has already tried
|
||||
to do the same thing as you. You may find the
|
||||
following resources helpful:
|
||||
</para>
|
||||
<para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
Search <ulink url="http://appdb.winehq.org">WineHQ's
|
||||
Application Database</ulink> to check for any tips
|
||||
relating to the program. If your specific version of
|
||||
the program isn't listed you may find a different one
|
||||
contains enough information to help you out.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<ulink url="http://www.frankscorner.org">Frank's Corner</ulink>
|
||||
contains a list of applications and detailed instructions
|
||||
for setting them up. Further help can be found in the user
|
||||
forums.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<ulink url="http://www.google.com">Google</ulink> can be
|
||||
useful depending on how you use it. You may
|
||||
find it helpful to search
|
||||
<ulink url="http://groups.google.com">Google Groups</ulink>,
|
||||
in particular the
|
||||
<ulink url="http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&group=comp.emulators.ms-windows.wine">comp.emulators.ms-windows.wine</ulink>
|
||||
group.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<ulink url="http://www.freenode.net">Freenode.net</ulink>
|
||||
hosts an IRC channel for Wine. You can access it by using
|
||||
any IRC client such as Xchat. The settings you'll need are:
|
||||
server = irc.freenode.net, port = 6667, and channel = #winehq
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
If you have a program that needs the Visual Basic Runtime Environment,
|
||||
you can download it from
|
||||
<ulink url="http://www.microsoft.com/downloads/details.aspx?FamilyID=bf9a24f9-b5c5-48f4-8edd-cdf2d29a79d5&DisplayLang=en/">this Microsoft site</ulink>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
If you know you are missing a DLL, such as mfc42,
|
||||
you may be able to find it at
|
||||
<ulink url="http://www.dll-files.com/">www.dll-files.com</ulink>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Wine's <ulink url="http://www.winehq.org/site/forums#ml">mailing
|
||||
lists</ulink> may also help, especially wine-users. The
|
||||
wine-devel list may be appropriate depending on the type of
|
||||
problem you are experiencing. If you post to wine-devel you
|
||||
should be prepared to do a little work to help diagnose the
|
||||
problem. Read the section below to find out how to debug
|
||||
the source of your problem.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
If all else fails, you may wish to investigate commercial
|
||||
versions of Wine to see if your application is supported.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Debug it!</title>
|
||||
|
||||
<para>
|
||||
Finding the source of your problem is the next step to take.
|
||||
There is a wide spectrum of possible problems
|
||||
ranging from simple configurations issues to completely unimplemented
|
||||
functionality in Wine. The next section will describe how to
|
||||
file a bug report and how to begin debugging a crash. For more
|
||||
information on using Wine's debugging facilities be sure to read
|
||||
the Wine Developers Guide.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1 id="bug-reporting">
|
||||
<title>How To Report A Bug</title>
|
||||
|
||||
<para>
|
||||
Please report all bugs along any relevant information to
|
||||
<ulink url="http://bugs.winehq.org/">Wine Bugzilla</ulink>.
|
||||
Please, search the Bugzilla database to check whether your problem
|
||||
is already reported. If it is already reported please add
|
||||
any relevant information to the original bug report.
|
||||
</para>
|
||||
|
||||
<sect2>
|
||||
<title>All Bug Reports</title>
|
||||
<para>
|
||||
Some simple advice on making your bug report more useful
|
||||
(and thus more likely to get answered and fixed):
|
||||
</para>
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
Post as much relevant information as possible.
|
||||
</para>
|
||||
<para>
|
||||
This means we need more information than a simple "MS
|
||||
Word crashes whenever I run it. Do you know why?"
|
||||
Include at least the following information:
|
||||
</para>
|
||||
<itemizedlist spacing="compact">
|
||||
<listitem>
|
||||
<para>
|
||||
Which version of Wine you're using (run <command>wine -v</command>)
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The name of the Operating system you're using, what distribution (if
|
||||
any), and what version. (i.e., Linux Red Hat 7.2)
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Which compiler and version, (run <command>gcc -v</command>).
|
||||
If you didn't compile wine then the name of the package and
|
||||
where you got it from.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Windows version, if used with Wine.
|
||||
Mention if you don't use Windows.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The name of the program you're trying to run, its version number,
|
||||
and a URL for where the program can be obtained (if
|
||||
available).
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The exact command line you used to start wine.
|
||||
(i.e., <command>wine "C:\Program Files\Test\program.exe"</command>).
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The exact steps required to reproduce the bug.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Any other information you think may be relevant or
|
||||
helpful, such as X server version in case of X
|
||||
problems, libc version etc.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Re-run the program with the WINEDEBUG environment variable <parameter>
|
||||
WINEDEBUG=+relay</parameter> option (i.e., <command>WINEDEBUG=+relay
|
||||
wine sol.exe</command>).
|
||||
</para>
|
||||
<para>
|
||||
This will output additional information at the console
|
||||
that may be helpful in debugging the program. It also
|
||||
slows the execution of program. There are some cases where
|
||||
the bug seems to disappear when <parameter> +relay
|
||||
</parameter> is used. Please mention that in the bug report.
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
</sect2>
|
||||
<sect2>
|
||||
<title>Crashes</title>
|
||||
<para>
|
||||
If Wine crashes while running your program, it is
|
||||
important that we have this information to have a chance
|
||||
at figuring out what is causing the crash. This can put
|
||||
out quite a lot (several MB) of information, though, so
|
||||
it's best to output it to a file. When the <prompt>Wine-dbg></prompt>
|
||||
prompt appears, type <userinput>quit</userinput>.
|
||||
</para>
|
||||
<para>
|
||||
You might want to try
|
||||
<parameter>+relay,+snoop</parameter> instead of
|
||||
<parameter>+relay</parameter>, but please note that
|
||||
<parameter>+snoop</parameter> is pretty unstable and
|
||||
often will crash earlier than a simple
|
||||
<parameter>+relay</parameter>! If this is the case, then
|
||||
please use <emphasis>only</emphasis> <parameter>+relay</parameter>!!
|
||||
A bug report with a crash in <parameter>+snoop</parameter>
|
||||
code is useless in most cases!
|
||||
You can also turn on other parameters, depending on the nature
|
||||
of the problem you are researching. See wine man page for full list
|
||||
of the parameters.
|
||||
</para>
|
||||
<para>
|
||||
To get the trace output, use one of the following methods:
|
||||
</para>
|
||||
<sect3>
|
||||
<title>The Easy Way</title>
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
This method is meant to allow even a total novice to
|
||||
submit a relevant trace log in the event of a crash.
|
||||
</para>
|
||||
<para>
|
||||
Your computer <emphasis>must</emphasis> have perl on it
|
||||
for this method to work. To find out if you have perl,
|
||||
run <command>which perl</command>. If it returns something like
|
||||
<filename>/usr/bin/perl</filename>, you're in business.
|
||||
Otherwise, skip on down to "The Hard Way". If you aren't
|
||||
sure, just keep on going. When you try to run the
|
||||
script, it will become <emphasis>very</emphasis> apparent
|
||||
if you don't have perl.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Change directory to <filename><dirs to wine>/tools</filename>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Type in <command>./bug_report.pl</command> and follow
|
||||
the directions.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Post the bug to
|
||||
<ulink url="http://bugs.winehq.org/">Wine Bugzilla</ulink>.
|
||||
Please, search Bugzilla database to check whether your problem is
|
||||
already found before posting a bug report.
|
||||
Include your own detailed description of the problem with
|
||||
relevant information. Attach the "Nice Formatted Report"
|
||||
to the submitted bug. Do not cut and paste the report
|
||||
in the bug description - it is pretty big.
|
||||
Keep the full debug output in case it will be needed by
|
||||
Wine developers.
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
</sect3>
|
||||
<sect3>
|
||||
<title>The Hard Way</title>
|
||||
<para>
|
||||
It is likely that only the last 100 or so lines of the
|
||||
trace are necessary to find out where the program crashes.
|
||||
In order to get those last 100 lines we need to do the following
|
||||
</para>
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
Redirect all the output of <parameter> WINEDEBUG </parameter>
|
||||
to a file.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Separate the last 100 lines to another file using
|
||||
<command>tail</command>.
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
<para>
|
||||
This can be done using one of the following methods.
|
||||
</para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>all shells:</term>
|
||||
<listitem>
|
||||
<screen>
|
||||
<prompt>$ </prompt>echo quit | WINEDEBUG=+relay wine [other_options] program_name >& filename.out;
|
||||
<prompt>$ </prompt>tail -n 100 filename.out > report_file
|
||||
</screen>
|
||||
<para>
|
||||
(This will print wine's debug messages only to the file
|
||||
and then auto-quit. It's probably a good idea to use this
|
||||
command, since wine prints out so many debug msgs that
|
||||
they flood the terminal, eating CPU cycles.)
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>tcsh and other csh-like shells:</term>
|
||||
<listitem>
|
||||
<screen>
|
||||
<prompt>$ </prompt>WINEDEBUG=+relay wine [other_options] program_name |& tee filename.out;
|
||||
<prompt>$ </prompt>tail -n 100 filename.out > report_file
|
||||
</screen>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>bash and other sh-like shells:</term>
|
||||
<listitem>
|
||||
<screen>
|
||||
<prompt>$ </prompt>WINEDEBUG=+relay wine [other_options] program_name 2>&1 | tee filename.out;
|
||||
<prompt>$ </prompt>tail -n 100 filename.out > report_file
|
||||
</screen>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
<para>
|
||||
<filename>report_file</filename> will now contain the
|
||||
last hundred lines of the debugging output, including
|
||||
the register dump and backtrace, which are the most
|
||||
important pieces of information. Please do not delete
|
||||
this part, even if you don't understand what it means.
|
||||
</para>
|
||||
<para>
|
||||
Post the bug to
|
||||
<ulink url="http://bugs.winehq.org/">Wine Bugzilla</ulink>.
|
||||
You need to attach the output file <filename>report_file</filename>
|
||||
from part 2). Along with the the relevant information
|
||||
used to create it. Do not cut and paste the report
|
||||
in the bug description - it is pretty big and it will
|
||||
make a mess of the bug report.
|
||||
If you do this, your chances of receiving some sort of
|
||||
helpful response should be very good.
|
||||
</para>
|
||||
<para>
|
||||
Please, search the Bugzilla database to check whether your problem
|
||||
is already reported. If it is already reported attach the
|
||||
output file <filename>report_file</filename> to the original
|
||||
bug report and add any other relevant information.
|
||||
</para>
|
||||
</sect3>
|
||||
</sect2>
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
||||
<!-- Keep this comment at the end of the file
|
||||
Local variables:
|
||||
mode: sgml
|
||||
sgml-parent-document:("wine-user.sgml" "set" "book" "chapter" "")
|
||||
End:
|
||||
-->
|
File diff suppressed because it is too large
Load diff
|
@ -1,173 +0,0 @@
|
|||
<chapter id="ddraw">
|
||||
<title>Outline of DirectDraw Architecture</title>
|
||||
|
||||
<para>
|
||||
This is an outline of the architecture. Many details are
|
||||
skipped, but hopefully this is useful.
|
||||
</para>
|
||||
|
||||
<sect1 id="ddinheritance">
|
||||
<title>DirectDraw inheritance tree</title>
|
||||
<programlisting>
|
||||
Main
|
||||
|
|
||||
User
|
||||
|-----------\
|
||||
XVidMode DGA2
|
||||
</programlisting>
|
||||
<para>
|
||||
Most of the DirectDraw functionality is implemented in a common base
|
||||
class. Derived classes are responsible for providing display
|
||||
mode functions (Enum, Set, Restore), GetCaps, GetDevice identifier
|
||||
and internal functions called to create primary and backbuffer
|
||||
surfaces.
|
||||
</para>
|
||||
<para>
|
||||
User provides for DirectDraw capabilities based on drawing to a
|
||||
Wine window. It uses the User DirectDrawSurface implementation
|
||||
for primary and backbuffer surfaces.
|
||||
</para>
|
||||
<para>
|
||||
XVidMode attempt to use the XFree86 VidMode extension to set the
|
||||
display resolution to match the parameters to SetDisplayMode.
|
||||
</para>
|
||||
<para>
|
||||
DGA2 attempt to use the XFree86 DGA 2.x extension to set the
|
||||
display resolution and direct access to the framebuffer, if the
|
||||
full-screen-exclusive cooperative level is used. If not, it just
|
||||
uses the User implementation.
|
||||
</para>
|
||||
</sect1>
|
||||
<sect1 id="ddsurfaceinheritance">
|
||||
<title>DirectDrawSurface inheritance tree</title>
|
||||
<programlisting>
|
||||
Main
|
||||
|--------------\
|
||||
| |
|
||||
DIB Fake Z-Buffer
|
||||
|
|
||||
|------\---------\
|
||||
| | |
|
||||
User DGA2 DIBTexture
|
||||
</programlisting>
|
||||
<para>
|
||||
Main provides a very simple base class that does not implement any of
|
||||
the image-related functions. Therefore it does not place any
|
||||
constraints on how the surface data is stored.
|
||||
</para>
|
||||
<para>
|
||||
DIB stores the surface data in a DIB section. It is used by the Main
|
||||
DirectDraw driver to create off-screen surfaces.
|
||||
</para>
|
||||
<para>
|
||||
User implements primary and backbuffer surfaces for the User DirectDraw
|
||||
driver. If it is a primary surface, it will attempt to keep itself
|
||||
synchronized to the window.
|
||||
</para>
|
||||
<para>
|
||||
DGA2 surfaces claims an appropriate section of framebuffer space and
|
||||
lets DIB build its DIB section on top of it.
|
||||
</para>
|
||||
<para>
|
||||
Fake Z-Buffer surfaces are used by Direct3D to indicate that a primary
|
||||
surface has an associated z-buffer. For a first implementation, it
|
||||
doesn't need to store any image data since it is just a placeholder.
|
||||
</para>
|
||||
<para>
|
||||
(Actually 3D programs will rarely use Lock or GetDC on primary
|
||||
surfaces, backbuffers or z-buffers so we may want to arrange for
|
||||
lazy allocation of the DIB sections.)
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="interfacethunks">
|
||||
<title>Interface Thunks</title>
|
||||
<para>
|
||||
Only the most recent version of an interface needs to be implemented.
|
||||
Other versions are handled by having thunks convert their parameters
|
||||
and call the root version.
|
||||
</para>
|
||||
<para>
|
||||
Not all interface versions have thunks. Some versions could be combined
|
||||
because their parameters were compatible. For example if a structure
|
||||
changes but the structure has a dwSize field, methods using that structure
|
||||
are compatible, as long as the implementation remembers to take the dwSize
|
||||
into account.
|
||||
</para>
|
||||
<para>
|
||||
Interface thunks for Direct3D are more complicated since the paradigm
|
||||
changed between versions.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="logicalobjectlayout">
|
||||
<title>Logical Object Layout</title>
|
||||
<para>
|
||||
The objects are split into the generic part (essentially the fields for
|
||||
Main) and a private part. This is necessary because some objects
|
||||
can be created with CoCreateInstance, then Initialized later. Only
|
||||
at initialization time do we know which class to use. Each class
|
||||
except Main declares a Part structure and adds that to its Impl.
|
||||
</para>
|
||||
<para>
|
||||
For example, the DIBTexture DirectDrawSurface implementation looks
|
||||
like this:
|
||||
</para>
|
||||
<programlisting>
|
||||
struct DIBTexture_DirectDrawSurfaceImpl_Part
|
||||
{
|
||||
union DIBTexture_data data; /*declared in the real header*/
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
struct DIB_DirectDrawSurfaceImpl_Part dib;
|
||||
struct DIBTexture_DirectDrawSurfaceImpl_Part dibtexture;
|
||||
} DIBTexture_DirectDrawSurfaceImpl;
|
||||
</programlisting>
|
||||
<para>
|
||||
So the DIBTexture surface class is derived from the DIB surface
|
||||
class and it adds one piece of data, a union.
|
||||
</para>
|
||||
<para>
|
||||
Main does not have a Part structure. Its fields are stored in
|
||||
IDirectDrawImpl/IDirectDrawSurfaceImpl.
|
||||
</para>
|
||||
<para>
|
||||
To access private data, one says
|
||||
</para>
|
||||
<programlisting>
|
||||
DIBTexture_DirectDrawSurfaceImpl* priv = This->private;
|
||||
do_something_with(priv->dibtexture.data);
|
||||
</programlisting>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="creatingobject">
|
||||
<title>Creating Objects</title>
|
||||
<para>
|
||||
Classes have two functions relevant to object creation, Create and
|
||||
Construct. To create a new object, the class' Create function is
|
||||
called. It allocates enough memory for IDirectDrawImpl or
|
||||
IDirectDrawSurfaceImpl as well as the private data for derived
|
||||
classes and then calls Construct.
|
||||
</para>
|
||||
<para>
|
||||
Each class's Construct function calls the base class's Construct,
|
||||
then does the necessary initialization.
|
||||
</para>
|
||||
<para>
|
||||
For example, creating a primary surface with the user ddraw driver
|
||||
calls User_DirectDrawSurface_Create which allocates memory for the
|
||||
object and calls User_DirectDrawSurface_Construct to initialize it.
|
||||
This calls DIB_DirectDrawSurface_Construct which calls
|
||||
Main_DirectDrawSurface_Construct.
|
||||
</para>
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
||||
<!-- Keep this comment at the end of the file
|
||||
Local variables:
|
||||
mode: sgml
|
||||
sgml-parent-document:("wine-devel.sgml" "set" "book" "chapter" "")
|
||||
End:
|
||||
-->
|
File diff suppressed because it is too large
Load diff
|
@ -1,495 +0,0 @@
|
|||
<chapter id="debugging">
|
||||
<title>Debug Logging</title>
|
||||
|
||||
<para>
|
||||
To better manage the large volume of debugging messages that
|
||||
Wine can generate, we divide the messages on a component basis,
|
||||
and classify them based on the severity of the reported problem.
|
||||
Therefore a message belongs to a <emphasis>channel</emphasis>
|
||||
and a <emphasis>class</emphasis> respectively.
|
||||
</para>
|
||||
<para>
|
||||
This section will describe the debugging classes, how you can
|
||||
create a new debugging channel, what the debugging API is,
|
||||
and how you can control the debugging output. A picture is
|
||||
worth a thousand words, so here are a few examples of the
|
||||
debugging API in action:
|
||||
<screen>
|
||||
ERR("lock_count == 0 ... please report\n");
|
||||
FIXME("Unsupported RTL style!\n");
|
||||
WARN(": file seems to be truncated!\n");
|
||||
TRACE("[%p]: new horz extent = %d\n", hwnd, extent );
|
||||
MESSAGE( "Could not create graphics driver '%s'\n", buffer );
|
||||
</screen>
|
||||
</para>
|
||||
|
||||
<sect1 id="dbg-classes">
|
||||
<title>Debugging classes</title>
|
||||
|
||||
<para>
|
||||
A debugging class categorizes a message based on the severity
|
||||
of the reported problem. There is a fixed set of classes, and
|
||||
you must carefully choose the appropriate one for your messages.
|
||||
There are five classes of messages:
|
||||
</para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><literal>FIXME</literal></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Messages in this class are meant to signal unimplemented
|
||||
features, known bugs, etc. They serve as a constant and
|
||||
active reminder of what needs to be done.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><literal>ERR</literal></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Messages in this class indicate serious errors in
|
||||
Wine, such as as conditions that should never happen
|
||||
by design.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><literal>WARN</literal></term>
|
||||
<listitem>
|
||||
<para>
|
||||
These are warning messages. You should report a
|
||||
warning when something unwanted happens, and the
|
||||
function cannot deal with the condition. This
|
||||
is seldomly used since proper functions can usually
|
||||
report failures back to the caller. Think twice before
|
||||
making the message a warning.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><literal>TRACE</literal></term>
|
||||
<listitem>
|
||||
<para>
|
||||
These are detailed debugging messages that are mainly
|
||||
useful to debug a component. These are turned off unless
|
||||
explicitly enabled.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><literal>MESSAGE</literal></term>
|
||||
<listitem>
|
||||
<para>
|
||||
There messages are intended for the end user. They do not
|
||||
belong to any channel. As with warnings, you will seldomly
|
||||
need to output such messages.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="dbg-channels">
|
||||
<title>Debugging channels</title>
|
||||
|
||||
<para>
|
||||
Each component is assigned a debugging channel. The
|
||||
identifier of the channel must be a valid C identifier
|
||||
(reserved word like <type>int</type> or <type>static</type>
|
||||
are premitted). To use a new channel, simply use it in
|
||||
your code. It will be picked up automatically by the build process.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Typically, a file contains code pertaining to only one component,
|
||||
and as such, there is only one channel to output to. You can declare
|
||||
a default chanel for the file using the
|
||||
<symbol>WINE_DEFAULT_DEBUG_CHANNEL()</symbol> macro:
|
||||
<programlisting>
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(xxx);
|
||||
...
|
||||
|
||||
FIXME("some unimplemented feature", ...);
|
||||
...
|
||||
if (zero != 0)
|
||||
ERR("This should never be non-null: %d", zero);
|
||||
...
|
||||
</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
In rare situations there is a need to output to more than one
|
||||
debug channel per file. In such cases, you need to declare
|
||||
all the additional channels at the top of the file, and
|
||||
use the _-version of the debugging macros:
|
||||
<programlisting>
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(xxx);
|
||||
WINE_DECLARE_DEBUG_CHANNEL(yyy);
|
||||
WINE_DECLARE_DEBUG_CHANNEL(zzz);
|
||||
...
|
||||
|
||||
FIXME("this one goes to xxx channel");
|
||||
...
|
||||
FIXME_(yyy)("Some other msg for the yyy channel");
|
||||
...
|
||||
WARN_(zzz)("And yet another msg on another channel!");
|
||||
...
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1 id="dbg-checking">
|
||||
<title>Are we debugging?</title>
|
||||
|
||||
<para>
|
||||
To test whether the debugging channel <literal>xxx</literal> is
|
||||
enabled, use the <symbol>TRACE_ON</symbol>, <symbol>WARN_ON</symbol>,
|
||||
<symbol>FIXME_ON</symbol>, or <symbol>ERR_ON</symbol> macros. For
|
||||
example:
|
||||
<programlisting>
|
||||
if(TRACE_ON(atom)){
|
||||
...blah...
|
||||
}
|
||||
</programlisting>
|
||||
You should normally need to test only if <literal>TRACE_ON</literal>,
|
||||
all the others are very seldomly used. With careful coding, you
|
||||
can avoid the use of these macros, which is generally desired.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="dbg-helpers">
|
||||
<title>Helper functions</title>
|
||||
|
||||
<para>
|
||||
Resource identifiers can be either strings or numbers. To
|
||||
make life a bit easier for outputting these beasts (and to
|
||||
help you avoid the need to build the message in memory), I
|
||||
introduced a new function called <function>debugres</function>.
|
||||
</para>
|
||||
<para>
|
||||
The function is defined in <filename>wine/debug.h</filename>
|
||||
and has the following prototype:
|
||||
</para>
|
||||
<programlisting>
|
||||
LPSTR debugres(const void *id);
|
||||
</programlisting>
|
||||
<para>
|
||||
It takes a pointer to the resource id and returns a nicely
|
||||
formatted string of the identifier (which can be a string or
|
||||
a number, depending on the value of the high word).
|
||||
Numbers are formatted as such:
|
||||
</para>
|
||||
<programlisting>
|
||||
#xxxx
|
||||
</programlisting>
|
||||
<para>
|
||||
while strings as:
|
||||
</para>
|
||||
<programlisting>
|
||||
'some-string'
|
||||
</programlisting>
|
||||
<para>
|
||||
Simply use it in your code like this:
|
||||
</para>
|
||||
<programlisting>
|
||||
#include "wine/debug.h"
|
||||
|
||||
...
|
||||
|
||||
TRACE("resource is %s", debugres(myresource));
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
Many times strings need to be massaged before output:
|
||||
they may be <literal>NULL</literal>, contain control
|
||||
characters, or they may be too long. Similarly, Unicode
|
||||
strings need to be converted to ASCII for usage with
|
||||
the debugging API. For all this, you can use the
|
||||
<function>debugstr_[aw]n?</function> familly of functions:
|
||||
<programlisting>
|
||||
HANDLE32 WINAPI YourFunc(LPCSTR s)
|
||||
{
|
||||
FIXME("(%s): stub\n", debugstr_a(s));
|
||||
}
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1 id="dbg-control">
|
||||
<title>Controlling the debugging output</title>
|
||||
|
||||
<para>
|
||||
It is possible to turn on and off debugging output from
|
||||
within the debugger using the set command. Please see the
|
||||
WineDbg Command Reference section
|
||||
(<xref linkend="winedbg-dbg-chan">) for how to do this.
|
||||
</para>
|
||||
<para>
|
||||
You can do the same using the task manager
|
||||
(<command>taskmgr</command>) and selecting your application in
|
||||
the application list. Right clicking on the application, and
|
||||
selecting the debug option in the popup menu, will let you
|
||||
select the modifications you want on the debug channels.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Another way to conditionally log debug output (e.g. in case of
|
||||
very large installers which may create gigabytes of log
|
||||
output) is to create a pipe:
|
||||
</para>
|
||||
<screen>
|
||||
<prompt>$</prompt> <userinput>mknod /tmp/debug_pipe p</userinput>
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
and then to run wine like that:
|
||||
</para>
|
||||
<screen>
|
||||
<prompt>$</prompt> <userinput>WINEDEBUG=+relay,+snoop wine setup.exe &>/tmp/debug_pipe</userinput>
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
Since the pipe is initially blocking (and thus wine as a whole),
|
||||
you have to activate it by doing:
|
||||
</para>
|
||||
<screen>
|
||||
<prompt>$</prompt> <userinput>cat /tmp/debug_pipe</userinput>
|
||||
</screen>
|
||||
<para>
|
||||
(press Ctrl-C to stop pasting the pipe content)
|
||||
</para>
|
||||
<para>
|
||||
Once you are about to approach the problematic part of the program,
|
||||
you just do:
|
||||
</para>
|
||||
<screen>
|
||||
<prompt>$</prompt> <userinput>cat /tmp/debug_pipe >/tmp/wine.log</userinput>
|
||||
</screen>
|
||||
<para>
|
||||
to capture specifically the part that interests you from the
|
||||
pipe without wasting excessive amounts of HDD space and
|
||||
slowing down installation considerably.
|
||||
</para>
|
||||
<para>
|
||||
The <parameter>WINEDEBUG</parameter> environment variable
|
||||
controls the output of the debug messages.
|
||||
It has the following syntax:
|
||||
<parameter>WINEDEBUG= [yyy]#xxx[,[yyy1]#xxx1]*</parameter>
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
where
|
||||
<literal>#</literal> is either <literal>+</literal> or
|
||||
<literal>-</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
when the optional class argument (<literal>yyy</literal>)
|
||||
is not present, then the statement will
|
||||
enable(<literal>+</literal>)/disable(<literal>-</literal>)
|
||||
all messages for the given channel (<literal>xxx</literal>)
|
||||
on all classes. For example:
|
||||
</para>
|
||||
<programlisting>
|
||||
WINEDEBUG=+reg,-file
|
||||
</programlisting>
|
||||
<para>
|
||||
enables all messages on the <literal>reg</literal>
|
||||
channel and disables all messages on the
|
||||
<literal>file</literal> channel.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
when the optional class argument (<literal>yyy</literal>)
|
||||
is present, then the statement will enable
|
||||
(<literal>+</literal>)/disable(<literal>-</literal>)
|
||||
messages for the given channel (<literal>xxx</literal>)
|
||||
only on the given class. For example:
|
||||
</para>
|
||||
<programlisting>
|
||||
WINEDEBUG=trace+reg,warn-file
|
||||
</programlisting>
|
||||
<para>
|
||||
enables trace messages on the <literal>reg</literal>
|
||||
channel and disables warning messages on the
|
||||
<literal>file</literal> channel.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
also, the pseudo-channel all is also supported and it
|
||||
has the intuitive semantics:
|
||||
</para>
|
||||
<screen>
|
||||
WINEDEBUG=+all -- enables all debug messages
|
||||
WINEDEBUG=-all -- disables all debug messages
|
||||
WINEDEBUG=yyy+all -- enables debug messages for class yyy on all
|
||||
channels.
|
||||
WINEDEBUG=yyy-all -- disables debug messages for class yyy on all
|
||||
channels.
|
||||
</screen>
|
||||
<para>
|
||||
So, for example:
|
||||
</para>
|
||||
<screen>
|
||||
WINEDEBUG=warn-all -- disables all warning messages.
|
||||
</screen>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>
|
||||
Also, note that at the moment:
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
the <literal>FIXME</literal> and <literal>ERR</literal>
|
||||
classes are enabled by default
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
the <literal>TRACE</literal> and <literal>WARN</literal>
|
||||
classes are disabled by default
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="dbg-compiling">
|
||||
<title>Compiling Out Debugging Messages</title>
|
||||
|
||||
<para>
|
||||
To compile out the debugging messages, provide
|
||||
<command>configure</command> with the following options:
|
||||
</para>
|
||||
<screen>
|
||||
--disable-debug -- turns off TRACE, WARN, and FIXME (and DUMP).
|
||||
--disable-trace -- turns off TRACE only.
|
||||
</screen>
|
||||
<para>
|
||||
This will result in an executable that, when stripped, is
|
||||
about 15%-20% smaller. Note, however, that you will not be
|
||||
able to effectively debug Wine without these messages.
|
||||
</para>
|
||||
<para>
|
||||
This feature has not been extensively tested--it may subtly
|
||||
break some things.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="dbg-notes">
|
||||
<title>A Few Notes on Style</title>
|
||||
|
||||
<para>
|
||||
This new scheme makes certain things more consistent but
|
||||
there is still room for improvement by using a common style
|
||||
of debug messages. Before I continue, let me note that the
|
||||
output format is the following:
|
||||
</para>
|
||||
<screen>
|
||||
yyy:xxx:fff <message>
|
||||
|
||||
where:
|
||||
yyy = the class (fixme, err, warn, trace)
|
||||
xxx = the channel (atom, win, font, etc)
|
||||
fff = the function name
|
||||
</screen>
|
||||
<para>
|
||||
these fields are output automatically. All you have to
|
||||
provide is the <message> part.
|
||||
</para>
|
||||
<para>
|
||||
So here are some ideas:
|
||||
</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
do not include the name of the function: it is included automatically
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
if you want to output the parameters of the function, do
|
||||
it as the first thing and include them in parentheses,
|
||||
like this:
|
||||
<programlisting>
|
||||
TRACE("(%d, %p, ...)\n", par1, par2, ...);
|
||||
</programlisting>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
if you want to name a parameter, use <literal>=</literal> :
|
||||
<programlisting>
|
||||
TRACE("(fd=%d, file=%s): stub\n", fd, name);
|
||||
</programlisting>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
for stubs, you should output a <literal>FIXME</literal>
|
||||
message. I suggest this style:
|
||||
<programlisting>
|
||||
FIXME("(%x, %d, ...): stub\n", par1, par2, ...);
|
||||
</programlisting>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
try to output one line per message. That is, the format
|
||||
string should contain only one <literal>\n</literal> and it
|
||||
should always appear at the end of the string.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
if the output string needs to be dynamically constructed,
|
||||
render it in memory before outputting it:
|
||||
<programlisting>
|
||||
char buffer[128] = "";
|
||||
|
||||
if (flags & FLAG_A) strcat(buffer, "FLAG_A ");
|
||||
if (flags & FLAG_B) strcat(buffer, "FLAG_B ");
|
||||
if (flags & FLAG_C) strcat(buffer, "FLAG_C ");
|
||||
TRACE("flags = %s\n", buffer);
|
||||
</programlisting>
|
||||
Most of the time however, it is better to create a helper
|
||||
function that renders to a temporary buffer:
|
||||
<programlisting>
|
||||
static const char *dbgstr_flags(int flags)
|
||||
{
|
||||
char buffer[128] = "";
|
||||
|
||||
if (flags & FLAG_A) strcat(buffer, "FLAG_A ");
|
||||
if (flags & FLAG_B) strcat(buffer, "FLAG_B ");
|
||||
if (flags & FLAG_C) strcat(buffer, "FLAG_C ");
|
||||
return wine_dbg_sprintf("flags = %s\n\n", buffer);
|
||||
}
|
||||
|
||||
...
|
||||
|
||||
TRACE("flags = %s\n", dbgstr_flags(flags));
|
||||
</programlisting>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</sect1>
|
||||
|
||||
</chapter>
|
||||
|
||||
<!-- Keep this comment at the end of the file
|
||||
Local variables:
|
||||
mode: sgml
|
||||
sgml-parent-document:("wine-devel.sgml" "set" "book" "part" "chapter" "")
|
||||
End:
|
||||
-->
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,501 +0,0 @@
|
|||
<sect1 id="config-fonts-main">
|
||||
<title>Dealing with Fonts</title>
|
||||
|
||||
<sect2 id="config-windows-fonts">
|
||||
<title>Fonts</title>
|
||||
|
||||
<para>
|
||||
<note>
|
||||
<para>
|
||||
The <command>fnt2bdf</command> utility is included with
|
||||
Wine. It can be found in the <filename>tools</filename>
|
||||
directory. Links to the other tools mentioned in this
|
||||
document can be found in the Wine Developer's Guide:
|
||||
<ulink url="http://www.winehq.org/site/docs/wine-devel/index">http://www.winehq.org/site/docs/wine-devel/index</ulink>
|
||||
</para>
|
||||
</note>
|
||||
</para>
|
||||
|
||||
<sect3>
|
||||
<title>How To Convert Windows Fonts</title>
|
||||
<para>
|
||||
If you have access to a Windows installation you should use the
|
||||
<command>fnt2bdf</command> utility (found in the
|
||||
<filename>tools</filename> directory) to convert bitmap
|
||||
fonts (<filename>VGASYS.FON</filename>,
|
||||
<filename>SSERIFE.FON</filename>, and
|
||||
<filename>SERIFE.FON</filename>) into the format that the X
|
||||
Window System can recognize.
|
||||
</para>
|
||||
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
Extract bitmap fonts with <command>fnt2bdf</command>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Convert <filename>.bdf</filename> files produced by Step
|
||||
1 into <filename>.pcf</filename> files with
|
||||
<command>bdftopcf</command>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Copy <filename>.pcf</filename> files to the font server
|
||||
directory which is usually
|
||||
<filename>/usr/lib/X11/fonts/misc</filename> (you will
|
||||
probably need superuser privileges). If you want to
|
||||
create a new font directory you will need to add it to
|
||||
the font path.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Run <command>mkfontdir</command> for the directory you
|
||||
copied fonts to. If you are already in X you should run
|
||||
<command>xset fp rehash</command> to make X server aware
|
||||
of the new fonts. You may also or instead have to restart
|
||||
the font server (using e.g.
|
||||
<command>/etc/init.d/xfs restart</command>
|
||||
under Red Hat 7.1)
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Edit the <filename>~/.wine/config</filename> file to remove
|
||||
aliases for the fonts you've just installed.
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
<para>
|
||||
Wine can get by without these fonts but 'the look and feel'
|
||||
may be quite different. Also, some applications try to load
|
||||
their custom fonts on the fly (WinWord 6.0) and since Wine
|
||||
does not implement this yet it instead prints out something
|
||||
like;
|
||||
</para>
|
||||
<screen>
|
||||
STUB: AddFontResource( SOMEFILE.FON )
|
||||
</screen>
|
||||
<para>
|
||||
You can convert this file too. Note that
|
||||
<filename>.FON</filename> file may not hold any bitmap
|
||||
fonts and <command>fnt2bdf</command> will fail if this is
|
||||
the case. Also note that although the above message will not
|
||||
disappear Wine will work around the problem by using the
|
||||
font you extracted from the
|
||||
<filename>SOMEFILE.FON</filename>.
|
||||
<command>fnt2bdf</command> will only work for Windows 3.1
|
||||
fonts. It will not work for TrueType fonts.
|
||||
</para>
|
||||
<para>
|
||||
What to do with TrueType fonts? There are several commercial
|
||||
font tools that can convert them to the Type1 format but the
|
||||
quality of the resulting fonts is far from stellar. The
|
||||
other way to use them is to get a font server capable of
|
||||
rendering TrueType (Caldera has one, there also is the free
|
||||
<command>xfstt</command> in
|
||||
<filename>Linux/X11/fonts</filename> on sunsite and mirrors,
|
||||
if you're on FreeBSD you can use the port in
|
||||
<filename>/usr/ports/x11-servers/Xfstt</filename>. And
|
||||
there is <command>xfsft</command> which uses the freetype
|
||||
library, see <link linkend="ttfont-server">freetype</link>
|
||||
description).
|
||||
</para>
|
||||
<para>
|
||||
However, there is a possibility of the native TrueType
|
||||
support via FreeType renderer in the future (hint, hint :-)
|
||||
</para>
|
||||
</sect3>
|
||||
|
||||
<sect3>
|
||||
<title>How To Add Font Aliases To <filename>~/.wine/config</filename></title>
|
||||
<para>
|
||||
Many Windows applications assume that fonts included in
|
||||
original Windows 3.1 distribution are always present. By
|
||||
default Wine creates a number of aliases that map them on
|
||||
the existing X fonts:
|
||||
</para>
|
||||
|
||||
<informaltable>
|
||||
<tgroup cols="3">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Windows font</entry>
|
||||
<entry>...is mapped to...</entry>
|
||||
<entry>X font</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>"MS Sans Serif"</entry>
|
||||
<entry align="center">-></entry>
|
||||
<entry>"-adobe-helvetica-"</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>"MS Serif"</entry>
|
||||
<entry align="center">-></entry>
|
||||
<entry>"-bitstream-charter-"</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>"Times New Roman"</entry>
|
||||
<entry align="center">-></entry>
|
||||
<entry>"-adobe-times-"</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>"Arial"</entry>
|
||||
<entry align="center">-></entry>
|
||||
<entry>"-adobe-helvetica-"</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</informaltable>
|
||||
|
||||
<para>
|
||||
There is no default alias for the "System" font. Also, no
|
||||
aliases are created for the fonts that applications install
|
||||
at runtime. The recommended way to deal with this problem
|
||||
is to convert the missing font (see above). If it proves
|
||||
impossible, like in the case with TrueType fonts, you can
|
||||
force the font mapper to choose a closely related X font by
|
||||
adding an alias to the [fonts] section. Make sure that the
|
||||
X font actually exists (with <command>xfontsel</command>
|
||||
tool).
|
||||
</para>
|
||||
<screen>
|
||||
AliasN = [Windows font], [X font] <, optional "mask X font" flag>
|
||||
</screen>
|
||||
<para>
|
||||
Example:
|
||||
</para>
|
||||
<screen>
|
||||
Alias0 = System, --international-, subst
|
||||
Alias1 = ...
|
||||
...
|
||||
</screen>
|
||||
<para>
|
||||
Comments:
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
There must be no gaps in the sequence <literal>{0, ...,
|
||||
N}</literal> otherwise all aliases after the first gap
|
||||
won't be read.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Usually font mapper translates X font names into font
|
||||
names visible to Windows programs in the following
|
||||
fashion:
|
||||
</para>
|
||||
|
||||
<informaltable>
|
||||
<tgroup cols="3">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>X font</entry>
|
||||
<entry>...will show up as...</entry>
|
||||
<entry>Extracted name</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>--international-...</entry>
|
||||
<entry align="center">-></entry>
|
||||
<entry>"International"</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>-adobe-helvetica-...</entry>
|
||||
<entry align="center">-></entry>
|
||||
<entry>"Helvetica"</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>-adobe-utopia-...</entry>
|
||||
<entry align="center">-></entry>
|
||||
<entry>"Utopia"</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>-misc-fixed-...</entry>
|
||||
<entry align="center">-></entry>
|
||||
<entry>"Fixed"</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>-...</entry>
|
||||
<entry align="center">-></entry>
|
||||
<entry></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>-sony-fixed-...</entry>
|
||||
<entry align="center">-></entry>
|
||||
<entry>"Sony Fixed"</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>-...</entry>
|
||||
<entry align="center">-></entry>
|
||||
<entry></entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</informaltable>
|
||||
|
||||
<para>
|
||||
Note that since <literal>-misc-fixed-</literal> and
|
||||
<literal>-sony-fixed-</literal> are different fonts Wine
|
||||
modified the second extracted name to make sure Windows
|
||||
programs can distinguish them because only extracted
|
||||
names appear in the font selection dialogs.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
"Masking" alias replaces the original extracted name so
|
||||
that in the example case we will have the following
|
||||
mapping:
|
||||
</para>
|
||||
<informaltable>
|
||||
<tgroup cols="3">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>X font</entry>
|
||||
<entry>...is masked to...</entry>
|
||||
<entry>Extracted name</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>--international-...</entry>
|
||||
<entry align="center">-></entry>
|
||||
<entry>"System"</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</informaltable>
|
||||
<para>
|
||||
"Nonmasking" aliases are transparent to the user and
|
||||
they do not replace extracted names.
|
||||
</para>
|
||||
<para>
|
||||
Wine discards an alias when it sees that the native X
|
||||
font is available.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
If you do not have access to Windows fonts mentioned in
|
||||
the first paragraph you should try to substitute the
|
||||
"System" font with nonmasking alias. The
|
||||
<command>xfontsel</command> application will show you
|
||||
the fonts available to X.
|
||||
</para>
|
||||
<screen>
|
||||
Alias.. = System, ...bold font without serifs
|
||||
</screen>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<para>
|
||||
Also, some Windows applications request fonts without
|
||||
specifying the typeface name of the font. Font table starts
|
||||
with Arial in most Windows installations, however X font
|
||||
table starts with whatever is the first line in the
|
||||
<filename>fonts.dir</filename>. Therefore Wine uses the
|
||||
following entry to determine which font to check first.
|
||||
</para>
|
||||
<para>
|
||||
Example:
|
||||
</para>
|
||||
<screen>
|
||||
Default = -adobe-times-
|
||||
</screen>
|
||||
<para>
|
||||
Comments:
|
||||
</para>
|
||||
<para>
|
||||
It is better to have a scalable font family (bolds and
|
||||
italics included) as the default choice because mapper
|
||||
checks all available fonts until requested height and other
|
||||
attributes match perfectly or the end of the font table is
|
||||
reached. Typical X installations have scalable fonts in the
|
||||
<filename>../fonts/Type1</filename> and
|
||||
<filename>../fonts/Speedo</filename> directories.
|
||||
</para>
|
||||
</sect3>
|
||||
|
||||
<sect3>
|
||||
<title>How To Manage Cached Font Metrics</title>
|
||||
<para>
|
||||
Wine stores detailed information about available fonts in
|
||||
the <filename>~/.wine/cachedmetrics.[display]</filename> file. You
|
||||
can copy it elsewhere and add this entry to the [fonts]
|
||||
section in your <filename>~/.wine/config</filename>:
|
||||
</para>
|
||||
<screen>
|
||||
FontMetrics = <file with metrics>
|
||||
</screen>
|
||||
<para>
|
||||
If Wine detects changes in the X font configuration it will
|
||||
rebuild font metrics from scratch and then it will overwrite
|
||||
<filename>~/.wine/cachedmetrics.[display]</filename> with the new
|
||||
information. This process can take a while.
|
||||
</para>
|
||||
</sect3>
|
||||
|
||||
<sect3>
|
||||
<title>Too Small Or Too Large Fonts</title>
|
||||
<para>
|
||||
Windows programs may ask Wine to render a font with the
|
||||
height specified in points. However, point-to-pixel ratio
|
||||
depends on the real physical size of your display (15",
|
||||
17", etc...). X tries to provide an estimate of that but it
|
||||
can be quite different from the actual size. You can change
|
||||
this ratio by adding the following entry to the [fonts]
|
||||
section:
|
||||
</para>
|
||||
<screen>
|
||||
Resolution = <integer value>
|
||||
</screen>
|
||||
<para>
|
||||
In general, higher numbers give you larger fonts. Try to
|
||||
experiment with values in the 60 - 120 range. 96 is a good
|
||||
starting point.
|
||||
</para>
|
||||
</sect3>
|
||||
|
||||
<sect3>
|
||||
<title>"FONT_Init: failed to load ..." Messages On Startup</title>
|
||||
<para>
|
||||
The most likely cause is a broken
|
||||
<filename>fonts.dir</filename> file in one of your font
|
||||
directories. You need to rerun <command>mkfontdir</command>
|
||||
to rebuild this file. Read its manpage for more information.
|
||||
If you can't run <command>mkfontdir</command> on this
|
||||
machine as you are not root, use <command>xset -fp
|
||||
xxx</command> to remove the broken font path.
|
||||
</para>
|
||||
</sect3>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="ttfont-server">
|
||||
<title>Setting up a TrueType Font Server</title>
|
||||
<para>
|
||||
Follow these instructions to set up a TrueType font server on your system.
|
||||
</para>
|
||||
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
Get a freetype source archive (<filename>freetype-X.Y.tar.gz</filename> ?).
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Read docs, unpack, configure and install
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Test the library, e.g. <command>ftview 20 /dosc/win95/fonts/times</command>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Get <filename>xfsft-beta1e.linux-i586</filename>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Install it and start it when booting, e.g. in an
|
||||
rc-script. The manpage for <command>xfs</command>
|
||||
applies.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Follow the hints given by <email>williamc@dai.ed.ac.uk</email>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
I got <command>xfsft</command> from
|
||||
<ulink url="http://www.dcs.ed.ac.uk/home/jec/progindex.html">http://www.dcs.ed.ac.uk/home/jec/progindex.html</ulink>.
|
||||
I have it running all the time. Here is
|
||||
<filename>/usr/X11R6/lib/X11/fs/config</filename>:
|
||||
</para>
|
||||
<programlisting>
|
||||
clone-self = on
|
||||
use-syslog = off
|
||||
catalogue = /c/windows/fonts
|
||||
error-file = /usr/X11R6/lib/X11/fs/fs-errors
|
||||
default-point-size = 120
|
||||
default-resolutions = 75,75,100,100
|
||||
</programlisting>
|
||||
<para>
|
||||
Obviously <filename>/c/windows/fonts</filename> is where
|
||||
my Windows fonts on my Win95 <medialabel>C:</medialabel>
|
||||
drive live; could be e.g.
|
||||
<filename>/mnt/dosC/windows/system</filename> for Win31.
|
||||
</para>
|
||||
<para>
|
||||
In <filename>/c/windows/fonts/fonts.scale</filename> I
|
||||
have:
|
||||
</para>
|
||||
<programlisting>
|
||||
14
|
||||
arial.ttf -monotype-arial-medium-r-normal--0-0-0-0-p-0-iso8859-1
|
||||
arialbd.ttf -monotype-arial-bold-r-normal--0-0-0-0-p-0-iso8859-1
|
||||
arialbi.ttf -monotype-arial-bold-o-normal--0-0-0-0-p-0-iso8859-1
|
||||
ariali.ttf -monotype-arial-medium-o-normal--0-0-0-0-p-0-iso8859-1
|
||||
cour.ttf -monotype-courier-medium-r-normal--0-0-0-0-p-0-iso8859-1
|
||||
courbd.ttf -monotype-courier-bold-r-normal--0-0-0-0-p-0-iso8859-1
|
||||
courbi.ttf -monotype-courier-bold-o-normal--0-0-0-0-p-0-iso8859-1
|
||||
couri.ttf -monotype-courier-medium-o-normal--0-0-0-0-p-0-iso8859-1
|
||||
times.ttf -monotype-times-medium-r-normal--0-0-0-0-p-0-iso8859-1
|
||||
timesbd.ttf -monotype-times-bold-r-normal--0-0-0-0-p-0-iso8859-1
|
||||
timesbi.ttf -monotype-times-bold-i-normal--0-0-0-0-p-0-iso8859-1
|
||||
timesi.ttf -monotype-times-medium-i-normal--0-0-0-0-p-0-iso8859-1
|
||||
symbol.ttf -monotype-symbol-medium-r-normal--0-0-0-0-p-0-microsoft-symbol
|
||||
wingding.ttf -microsoft-wingdings-medium-r-normal--0-0-0-0-p-0-microsoft-symbol
|
||||
</programlisting>
|
||||
<para>
|
||||
In <filename>/c/windows/fonts/fonts.dir</filename> I have
|
||||
exactly the same.
|
||||
</para>
|
||||
<para>
|
||||
In <filename>/usr/X11R6/lib/X11/XF86Config</filename> I have
|
||||
</para>
|
||||
<programlisting>
|
||||
FontPath "tcp/localhost:7100"
|
||||
</programlisting>
|
||||
<para>
|
||||
in front of the other <literal>FontPath</literal> lines.
|
||||
That's it! As an interesting by-product of course, all
|
||||
those web pages which specify Arial come up in Arial in
|
||||
Netscape ...
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Shut down X and restart (and debug errors you did while
|
||||
setting up everything).
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Test with e.g. <command>xlsfont | grep arial</command>
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
|
||||
</sect2>
|
||||
|
||||
</sect1>
|
||||
|
||||
<!-- Keep this comment at the end of the file
|
||||
Local variables:
|
||||
mode: sgml
|
||||
sgml-parent-document:("wine-user.sgml" "set" "book" "chapter" "")
|
||||
End:
|
||||
-->
|
|
@ -1,202 +0,0 @@
|
|||
<chapter id="getting-wine">
|
||||
<title>Getting Wine</title>
|
||||
<sect1 id="installation-methods">
|
||||
<title>Wine Installation Methods</title>
|
||||
<para>
|
||||
Once you've decided that Wine is right for your needs, the next step is
|
||||
to decide how you want to install it. There are three methods for
|
||||
installing Wine from WineHQ, each with their own advantages and
|
||||
disadvantages.
|
||||
</para>
|
||||
|
||||
<sect2 id="installation-methods-package">
|
||||
<title>Installation from a package</title>
|
||||
<para>
|
||||
By far the easiest method for installing Wine is to use a prepackaged
|
||||
version of Wine. These packages contain ready-to-run Wine binary
|
||||
files specifically compiled for your distribution, and they are
|
||||
tested regularly by the packagers for both functionality and
|
||||
completeness.
|
||||
</para>
|
||||
<para>
|
||||
Packages are the recommended method for installing Wine. We make
|
||||
them easily available at the
|
||||
<ulink url="http://www.winehq.org/site/download">WineHQ downloads page
|
||||
</ulink>, and these are always the latest packages available. Being
|
||||
popular, Wine packages can also be found elsewhere in official
|
||||
distribution repositories. These can, however, sometimes be out of
|
||||
date, depending on the distribution. Packages are easily upgradable
|
||||
as well, and many distributions can upgrade Wine seamlessly with a
|
||||
few clicks. Building your own installable binary package from a
|
||||
source package is also possible, although it is beyond the scope of
|
||||
this guide.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="installation-methods-source">
|
||||
<title>Installation from a source archive</title>
|
||||
<para>
|
||||
Sometimes the Wine packages don't fit your needs exactly. Perhaps
|
||||
they're not available for your architecture or distribution, or
|
||||
perhaps you want to build wine using your own compiler optimizations
|
||||
or with some options disabled, or perhaps you need to modify a
|
||||
specific part of the source code before compilation. Being an open
|
||||
source project, you are free to do all of these things with Wine's
|
||||
source code, which is provided with every Wine release. This method
|
||||
of installation can be done by downloading a Wine source archive and
|
||||
compiling from the command line. If you are comfortable with such
|
||||
things and have special needs, this option may be for you.
|
||||
</para>
|
||||
<para>
|
||||
Getting Wine source archives is simple. Every release, we put a
|
||||
source package in compressed tar.gz format at the
|
||||
<ulink url="http://www.winehq.org/site/download">WineHQ downloads
|
||||
page</ulink>. Compiling and installing Wine from source is slightly
|
||||
more difficult than using a package, however we will cover it in
|
||||
depth and attempt to hold your hand along the way.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="installation-methods-cvs">
|
||||
<title>Installation from a cvs snapshot</title>
|
||||
<para>
|
||||
If you wish to try out the bleeding edge of Wine development, or
|
||||
would even like to help develop Wine yourself, you can download the
|
||||
very latest source code from our CVS server. Instructions for
|
||||
downloading from the Wine cvs repository are available at <ulink
|
||||
url="http://www.winehq.org/site/cvs">http://www.winehq.org/site/cvs
|
||||
</ulink>.
|
||||
</para>
|
||||
<para>
|
||||
Please take note that the usual warnings for using a developmental
|
||||
version still apply. The source code on the CVS server is largely
|
||||
untested and may not even compile properly. It is, however, the
|
||||
best way to test out how Wine will work in the next version, and if
|
||||
you're modifying source code it's best to get the latest copy. The
|
||||
CVS repository is also useful for application maintainers interested
|
||||
in testing if an application will still work right for the next
|
||||
release, or if a recent patch actually improves things. If you're
|
||||
interested in helping us to get an application working in Wine, see
|
||||
the <ulink url="http://www.winehq.org/site/helping-applications">
|
||||
guide to helping applications work</ulink>.
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="installing-wine-package">
|
||||
<title>Installing Wine from a package</title>
|
||||
<sect2>
|
||||
<title>Installing a fresh package</title>
|
||||
<para>
|
||||
Installing a package on a fresh system is remarkably straightforward.
|
||||
Simply download and install the package using whatever utility your
|
||||
distribution provides. There is usually no need to explicitly
|
||||
remove old packages before installing, as modern Linux distributions
|
||||
should upgrade and replace them automatically. If you installed
|
||||
Wine from source code, however, you should remove it before
|
||||
installing a Wine package. See the section on <link
|
||||
linkend="uninstalling-wine-source">uninstalling Wine from source
|
||||
</link> for proper instructions.
|
||||
</para>
|
||||
</sect2>
|
||||
<sect2>
|
||||
<title>Different Distributions</title>
|
||||
<para>
|
||||
Wine works on a huge amount of different Linux distributions, as well
|
||||
other Unix-like systems such as Solaris and FreeBSD, each with their
|
||||
own specific way of installing and managing packages. Fortunately,
|
||||
however, the same general ideas apply to all of them, and installing
|
||||
Wine should be no more difficult than installing any other software,
|
||||
no matter what distribution you use. Uninstalling Wine packages is
|
||||
simple as well, and in modern Linux distributions is usually done
|
||||
through the same easy interface as package installation.
|
||||
</para>
|
||||
<para>
|
||||
We won't cover the specifics of installing or uninstalling Wine
|
||||
packages among the various systems' methods of packaging and package
|
||||
management in this guide, however, up to date installation notes for
|
||||
particular distributions can be found at the WineHQ website in the
|
||||
<ulink url="http://www.winehq.org/site/howto">HowTo</ulink>.
|
||||
If you need further help figuring
|
||||
out how to simply install a Wine package, we suggest consulting your
|
||||
distribution's documentation, support forums, or IRC channels.
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="installing-wine-source">
|
||||
<title>Installing Wine from source</title>
|
||||
<para>
|
||||
Before installing Wine from source, make sure you uninstall any Wine
|
||||
binary packages you may have on your system. Installing from source
|
||||
requires use of the terminal window as well as a full copy of the
|
||||
Wine source code. Once having downloaded the source from CVS or
|
||||
extracted it from an archive, navigate to it using the terminal and
|
||||
then follow the remaining steps.
|
||||
</para>
|
||||
<sect2>
|
||||
<title>Getting the Build Dependencies</title>
|
||||
<para>
|
||||
Wine makes use of many open source libraries during its operation.
|
||||
While Wine is not strictly dependent on these libraries and will
|
||||
compile without most of them, much of Wine's functionality is
|
||||
improved by having them available at compile time. In the past,
|
||||
many user problems were caused by people not having the necessary
|
||||
development libraries when they built Wine from source; because of
|
||||
this reason and others, we highly recommend installing via binary
|
||||
packages or by building source packages which can automatically
|
||||
satisfy their build dependencies.
|
||||
</para>
|
||||
<para>
|
||||
If you wish to install build dependencies by hand, there are several
|
||||
ways to see if you're missing some useful development libraries.
|
||||
The most straightforward approach is to watch the configure program's
|
||||
output before you compile Wine and see if anything important is
|
||||
missing; if it is, simply install what's missing and rerun configure
|
||||
before compiling. You can also check the file configure generates,
|
||||
(include/config.h.in) and see if what files configure is looking for
|
||||
but not finding.
|
||||
</para>
|
||||
</sect2>
|
||||
<sect2 id="compiling-wine">
|
||||
<title>Compiling Wine</title>
|
||||
<para>
|
||||
Once you've installed the build dependencies you need, you're ready
|
||||
to compile the package. In the terminal window, after having
|
||||
navigated to the Wine source tree, run the following commands:
|
||||
<screen>
|
||||
<prompt>$ </><userinput>./configure</>
|
||||
<prompt># </><userinput>make depend</>
|
||||
<prompt># </><userinput>make</>
|
||||
<prompt># </><userinput>make install</>
|
||||
</screen>
|
||||
The last command requires root privileges. Although you should
|
||||
never run Wine as root, you will need to install it this way.
|
||||
</para>
|
||||
</sect2>
|
||||
<sect2 id="uninstalling-wine-source">
|
||||
<title>Uninstalling Wine from Source</title>
|
||||
<para>
|
||||
To uninstall Wine from source, once again navigate to the same
|
||||
source folder that you used to install Wine using the terminal.
|
||||
Then, run the following command:
|
||||
<screen>
|
||||
<prompt># </><userinput>make uninstall</>
|
||||
</screen>
|
||||
This command will require root privileges, and should remove all of
|
||||
the Wine binary files from your system. It will not, however,
|
||||
remove your Wine configuration and applications located in your
|
||||
user's home directory, so you are free to install another version of
|
||||
Wine or delete that configuration by hand.
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
</chapter>
|
||||
|
||||
<!-- Keep this comment at the end of the file
|
||||
Local variables:
|
||||
mode: sgml
|
||||
sgml-parent-document:("wine-user.sgml" "set" "book" "chapter" "")
|
||||
End:
|
||||
-->
|
|
@ -1,188 +0,0 @@
|
|||
<glossary id="glossary">
|
||||
<title>Glossary</title>
|
||||
<!--
|
||||
EXAMPLE:
|
||||
<glossdiv>
|
||||
<title>test</title>
|
||||
<glossentry sortas="rme">
|
||||
<glossterm id="bad_mistake">Very Stupid Mistake</glossterm>
|
||||
<glosssee>things_to_avoid</glosssee>
|
||||
<acronym>VSM</acronym>
|
||||
<abbrev>Doh!</abbrev>
|
||||
<glossseealso otherterm="accident">
|
||||
<glossdef>
|
||||
<para>Something you should try to avoid at all costs.</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
-->
|
||||
<glossdiv>
|
||||
<title></title>
|
||||
<glossentry>
|
||||
<glossterm>Binary</glossterm>
|
||||
<glossdef>
|
||||
<para>
|
||||
A file which is in machine executable, compiled form: hex data (as opposed to a source code file).
|
||||
</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
<glossentry>
|
||||
<glossterm>CVS</glossterm>
|
||||
<glossdef>
|
||||
<para>
|
||||
Concurrent Versions System, a software package to manage software development done by several people. See the CVS chapter in the Wine Developers Guide for detailed usage information.
|
||||
</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
<glossentry>
|
||||
<glossterm>Distribution</glossterm>
|
||||
<glossdef>
|
||||
<para>
|
||||
A distribution is usually the way in which some "vendor" ships operating system CDs (usually mentioned in the context of Linux).
|
||||
A Linux environment can be shipped in lots of different configurations: e.g. distributions could be built to be suitable for games, scientific
|
||||
applications, server operation, desktop systems, etc.
|
||||
</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
<glossentry>
|
||||
<glossterm>DLL</glossterm>
|
||||
<glossdef>
|
||||
<para>
|
||||
A DLL (Dynamic Link Library) is a file that can be loaded and executed by programs dynamically. Basically it's an external code repository for programs.
|
||||
Since usually several different programs reuse the same DLL instead of having that code in their own file, this dramatically reduces required storage space.
|
||||
A synonym for a DLL would be library.
|
||||
</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
<glossentry>
|
||||
<glossterm>Editor</glossterm>
|
||||
<glossdef>
|
||||
<para>
|
||||
An editor is usually a program to create or modify text files.
|
||||
There are various graphical and text mode editors available on
|
||||
Linux.
|
||||
</para>
|
||||
<para>
|
||||
Examples of graphical editors are: nedit, gedit, kedit, xemacs,
|
||||
gxedit.
|
||||
</para>
|
||||
<para>
|
||||
Examples of text mode editors are: joe, ae, emacs, vim, vi.
|
||||
In a <glossterm>terminal</glossterm>, simply run them via:
|
||||
</para>
|
||||
<screen>
|
||||
<prompt>$ </><userinput><replaceable>editorname</replaceable>
|
||||
<replaceable>filename</replaceable></>
|
||||
</screen>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
<glossentry>
|
||||
<glossterm>Environment variable</glossterm>
|
||||
<glossdef>
|
||||
<para>
|
||||
Environment variables are text definitions used in a <glossterm>Shell</glossterm> to store important system settings.
|
||||
In a <command>bash</command> shell (the most commonly used one in Linux),
|
||||
you can view all environment variables by executing:
|
||||
</para>
|
||||
<screen>
|
||||
<userinput>set</userinput>
|
||||
</screen>
|
||||
<para>
|
||||
If you want to change an environment variable, you could run:
|
||||
</para>
|
||||
<screen>
|
||||
<userinput>export <replaceable>MYVARIABLE</>=<replaceable>mycontent</></userinput>
|
||||
</screen>
|
||||
<para>
|
||||
For deleting an environment variable, use:
|
||||
</para>
|
||||
<screen>
|
||||
<userinput>unset <replaceable>MYVARIABLE</></userinput>
|
||||
</screen>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
<glossentry>
|
||||
<glossterm>Package</glossterm>
|
||||
<glossdef>
|
||||
<para>
|
||||
A package is a compressed file in a
|
||||
<glossterm>distribution</glossterm> specific format. It contains the
|
||||
files for a particular program you want to install. Packages are
|
||||
usually installed via the <command>dpkg</command> or
|
||||
<command>rpm</command> package managers.
|
||||
</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
<glossentry>
|
||||
<glossterm>root</glossterm>
|
||||
<glossdef>
|
||||
<para>
|
||||
root is the account name of the system administrator.
|
||||
In order to run programs as root, simply open a
|
||||
<glossterm>Terminal</glossterm> window, then run:
|
||||
</para>
|
||||
<screen>
|
||||
<prompt>$ </><userinput>su -</>
|
||||
</screen>
|
||||
<para>
|
||||
This will prompt you for the password of the root user of your system,
|
||||
and after that you will be able to system administration tasks
|
||||
that require special root privileges. The root account is indicated by the
|
||||
</para>
|
||||
<screen>
|
||||
<prompt># </>
|
||||
</screen>
|
||||
<para>
|
||||
prompt, whereas '$' indicates a normal user account.
|
||||
</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
<glossentry>
|
||||
<glossterm>Shell</glossterm>
|
||||
<glossdef>
|
||||
<para>
|
||||
A shell is a tool to enable users to interact with the
|
||||
system. Usually shells are text based and command line oriented.
|
||||
Examples of popular shells include <command>bash</command>,
|
||||
<command>tcsh</command> and <command>ksh</command>. Wine assumes
|
||||
that for Wine installation tasks, you use <command>bash</command>,
|
||||
since this is the most popular shell on Linux.
|
||||
Shells are usually run in a <glossterm>Terminal</glossterm> window.
|
||||
</para>
|
||||
<!-- <glossseealso otherterm="Terminal"> -->
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
<glossentry>
|
||||
<glossterm>Source code</glossterm>
|
||||
<glossdef>
|
||||
<para>
|
||||
Source code is the code that a program consists of before the program
|
||||
is being compiled, i.e. it's the original building instructions of a
|
||||
program that tell a compiler what the program should look like once
|
||||
it's been compiled to a <glossterm>Binary</glossterm>.
|
||||
</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
<glossentry>
|
||||
<glossterm>Terminal</glossterm>
|
||||
<glossdef>
|
||||
<para>
|
||||
A terminal window is usually a graphical window that one uses to
|
||||
execute a <command>Shell</command>. If Wine asks you to open a
|
||||
terminal, then you usually need to click on an icon on your desktop
|
||||
that shows a big black window (or, in other cases, an icon displaying a
|
||||
maritime shell).
|
||||
Wine assumes you're using the <command>bash</command> shell in a
|
||||
terminal window, so if your terminal happens to use a different
|
||||
shell program, simply type:
|
||||
</para>
|
||||
<screen>
|
||||
<userinput>bash</>
|
||||
</screen>
|
||||
<para>
|
||||
in the terminal window.
|
||||
</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
</glossary>
|
|
@ -1,366 +0,0 @@
|
|||
<chapter id="introduction">
|
||||
<title>Introduction</title>
|
||||
|
||||
<sect1 id="overview">
|
||||
<title>Overview / About</title>
|
||||
|
||||
<sect2>
|
||||
<title>Purpose of this document and intended audience</title>
|
||||
<para>
|
||||
This document, called the Wine User Guide, is both an easy
|
||||
installation guide and an extensive reference guide. This guide
|
||||
is for both the new Wine user and the experienced Wine user,
|
||||
offering full step-by-step installation and configuration
|
||||
instructions, as well as featuring extensive reference material
|
||||
by documenting all configuration features and support areas.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Further questions and comments</title>
|
||||
<para>
|
||||
If, after examining this guide, the FAQ, and other relevant
|
||||
documentation there is still something you cannot figure out,
|
||||
we would love to hear from you. The <ulink
|
||||
url="http://www.winehq.org/site/forums">mailing lists</ulink>
|
||||
section contains several mailing lists and an IRC channel, all
|
||||
of which are great places to seek help and offer suggestions.
|
||||
If you are particularly savvy, and believe that something can be
|
||||
explained better, you can file a <ulink
|
||||
url="http://bugs.winehq.org/">bug report</ulink> or <ulink
|
||||
url="http://www.winehq.org/site/sending_patches">post a
|
||||
patch</ulink> on Wine's documentation itself.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Content overview / Steps to take</title>
|
||||
<para>
|
||||
In order to be able to use Wine, you must first have a working
|
||||
installation. This guide will help you to move your system
|
||||
from an empty, Wineless void to one boasting a fresh, up to
|
||||
date Wine install. The first step, <link
|
||||
linkend="getting-wine">Getting Wine</link>, illustrates the
|
||||
various methods of getting Wine's files onto your computer.
|
||||
The second step, <link linkend="config-wine-main">Configuring
|
||||
Wine</link>, shows how to customize a Wine installation depending
|
||||
on your individual needs. The final step, <link
|
||||
linkend="running">Running Wine</link>, covers the specific
|
||||
steps you can take to get a particular application to run
|
||||
better under Wine, and provides useful links in case you need
|
||||
further help.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1 id="what-is-wine">
|
||||
<title>What is Wine?</title>
|
||||
|
||||
<sect2>
|
||||
<title>Windows and Linux</title>
|
||||
<para>
|
||||
Different software programs are designed for different
|
||||
operating systems, and most won't work on systems that they
|
||||
weren't designed for. Windows programs, for example, won't run
|
||||
in Linux because they contain instructions that the system can't
|
||||
understand until they're translated by the Windows environment.
|
||||
Linux programs, likewise, won't run under the Windows operating
|
||||
system because Windows is unable to interpret all of their
|
||||
instructions.
|
||||
</para>
|
||||
<para>
|
||||
This situation presents a fundamental problem for anyone who
|
||||
wants to run software for both Windows and Linux. A common
|
||||
solution to this problem is to install both operating systems on
|
||||
the same computer, known as "dual booting." When a Windows
|
||||
program is needed, the user boots the machine into Windows to
|
||||
run it; when a Linux program is then needed, the user then
|
||||
reboots the machine into Linux. This option presents great
|
||||
difficulty: not only must the user endure the frustration of
|
||||
frequent rebooting, but programs for both platforms can't be
|
||||
run simultaneously. Having Windows on a system also creates
|
||||
an added burden: the software is expensive, requires a separate
|
||||
disk partition, and is unable to read most filesystem formats,
|
||||
making the sharing of data between operating systems difficult.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>What is Wine, and how can it help me?</title>
|
||||
<para>
|
||||
Wine makes it possible to run Windows programs alongside any
|
||||
Unix-like operating system, particularly Linux. At its heart,
|
||||
Wine is an implementation of the Windows Application
|
||||
Programing Interface (API) library, acting as a bridge between
|
||||
the Windows program and Linux. Think of Wine as a compatibility
|
||||
layer, when a Windows program tries to perform a function that
|
||||
Linux doesn't normally understand, Wine will translate that
|
||||
program's instruction into one supported by the system. For
|
||||
example, if a program asks the system to create a Windows
|
||||
pushbutton or text-edit field, Wine will convert that
|
||||
instruction into its Linux equivalent in the form of a command
|
||||
to the window manager using the standard X11 protocol.
|
||||
</para>
|
||||
<para>
|
||||
If you have access to the Windows program's source code, Wine
|
||||
can also be used to recompile a program into a format that Linux
|
||||
can understand more easily. Wine is still needed to launch the
|
||||
program in its recompiled form, however there are many advantages
|
||||
to compiling a Windows program natively within Linux. For more
|
||||
information, see the Winelib User Guide.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="wine-features">
|
||||
<title>Wine features</title>
|
||||
|
||||
<para>
|
||||
Throughout the course of its development, Wine has continually
|
||||
grown in the features it carries and the programs it can run.
|
||||
A partial list of these features follows:
|
||||
</para>
|
||||
<para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
Support for running Win32 (Win 95/98, NT/2000/XP), Win16
|
||||
(Win 3.1) and DOS programs
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Optional use of external vendor DLL files (such as those
|
||||
included with Windows)
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
X11-based graphics display, allowing remote display to any
|
||||
X terminal, as well as a text mode console
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Desktop-in-a-box or mixable windows
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
DirectX support for games
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Good support for various sound drivers including OSS and ALSA
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Support for alternative input devices
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Printing: PostScript interface driver (psdrv) to standard
|
||||
Unix PostScript print services
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Modem, serial device support
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Winsock TCP/IP networking support
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
ASPI interface (SCSI) support for scanners, CD writers,
|
||||
and other devices
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Advanced unicode and foreign language support
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Full-featured Wine debugger and configurable trace
|
||||
logging messages for easier troubleshooting
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="wine-versions">
|
||||
<title>Versions of Wine</title>
|
||||
<sect2>
|
||||
<title>Wine from Wine HQ</title>
|
||||
|
||||
<para>
|
||||
Wine is an open source project, and there are accordingly
|
||||
many different versions of Wine for you to choose from. The
|
||||
standard version of Wine comes in intermittant releases
|
||||
(roughly once a month), and can be downloaded over the
|
||||
internet in both prepackaged binary form and ready to compile
|
||||
source code form. Alternatively, you can install a development
|
||||
version of Wine by using the latest available source code on
|
||||
the CVS server. See the next chapter, <link
|
||||
linkend="getting-wine">Getting Wine</link>, for further details.
|
||||
</para>
|
||||
</sect2>
|
||||
<sect2>
|
||||
<title>Other Versions of Wine</title>
|
||||
<para>
|
||||
There are a number of programs that are derived from the
|
||||
standard Wine codebase in some way or another. Some of these
|
||||
are commercial products from companies that actively contribute
|
||||
to the Wine project.
|
||||
</para>
|
||||
<para>
|
||||
These products try to stand out or distinguish themselves
|
||||
from the standard version of Wine by offering greater
|
||||
compatibility, easier configuration, and commercial support.
|
||||
If you require such things, it is a good idea to consider
|
||||
purchasing these products.
|
||||
</para>
|
||||
<table><title>Various Wine offerings</title>
|
||||
<tgroup cols=3 align="left">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Product</entry>
|
||||
<entry>Description</entry>
|
||||
<entry>Distribution Form</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>
|
||||
<ulink
|
||||
url="http://www.codeweavers.com/products/office">CodeWeavers CrossOver Office</ulink>
|
||||
</entry>
|
||||
<entry>
|
||||
CrossOver Office allows you to install your favorite
|
||||
Windows productivity applications in Linux, without
|
||||
needing a Microsoft Operating System license. CrossOver
|
||||
includes an easy to use, single click interface, which
|
||||
makes installing a Windows application simple and fast.
|
||||
</entry>
|
||||
<entry>
|
||||
Commercial; 30-day fully-functional demo available.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<ulink
|
||||
url="http://www.codeweavers.com/products/cxofficeserver">CodeWeavers CrossOver Office Server Edition</ulink>
|
||||
</entry>
|
||||
<entry>
|
||||
CrossOver Office Server Edition allows you to run your
|
||||
favorite Windows productivity applications in a
|
||||
distributed thin-client environment under Linux, without
|
||||
needing Microsoft Operating System licenses for each
|
||||
client machine. CrossOver Office Server Edition allows you
|
||||
to satisfy the needs of literally hundreds of concurrent
|
||||
users, all from a single server.
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="alternatives">
|
||||
<title>Alternatives to Wine you might want to consider</title>
|
||||
<para>
|
||||
There are many ways to run software other than through Wine. If
|
||||
you are considering using Wine to run an application you might
|
||||
want to think about the viability of these approaches if you
|
||||
encounter difficulty.
|
||||
</para>
|
||||
|
||||
<sect2>
|
||||
<title>Native Applications</title>
|
||||
<para>
|
||||
Instead of running a particular Windows application with Wine,
|
||||
one frequently viable alternative is to simply run a different
|
||||
application. Many Windows applications, particularly more
|
||||
commonly used ones such as media players, instant messengers,
|
||||
and filesharing programs have very good open source equivalents.
|
||||
Furthermore, a sizable number of Windows programs have been
|
||||
ported to Linux directly, eliminating the need for Wine (or
|
||||
Windows) entirely.
|
||||
</para>
|
||||
</sect2>
|
||||
<sect2>
|
||||
<title>Another Operating System</title>
|
||||
<para>
|
||||
Probably the most obvious method of getting a Windows
|
||||
application to run is to simply run it on Windows. However,
|
||||
security, license cost, backward-compatibility, and machine
|
||||
efficiency issues can make this a difficult proposition, which
|
||||
is why Wine is so useful in the first place.
|
||||
</para>
|
||||
<para>
|
||||
Another alternative is to use <ulink
|
||||
url="http://www.reactos.com">ReactOS</ulink>, which is a fully
|
||||
open source alternative to Windows. ReactOS shares code
|
||||
heavily with the Wine project, but rather than running Windows
|
||||
applications on top of Linux they are instead run on top of the
|
||||
ReactOS kernel. ReactOS also offers compatibility with Windows
|
||||
driver files, allowing the use of hardware without functional
|
||||
Linux drivers.
|
||||
</para>
|
||||
</sect2>
|
||||
<sect2>
|
||||
<title>Virtual Machines</title>
|
||||
<para>
|
||||
Rather than installing an entirely new operating system on your
|
||||
machine, you can instead run a virtual machine at the software
|
||||
level and install a different operating system on it. Thus, you
|
||||
could run a Linux system and at the same time run Windows along
|
||||
with your application in a virtual machine simultaneously on the
|
||||
same hardware. Virtual machines allow you to install and run
|
||||
not only different versions of Windows on the same hardware, but
|
||||
also other operating systems, including ReactOS.
|
||||
</para>
|
||||
<para>
|
||||
There are several different virtual machine offerings out there,
|
||||
and some are also able to emulate x86 hardware on different
|
||||
platforms. The open source <ulink
|
||||
url="http://bochs.sourceforge.net/">Bochs</ulink> and <ulink
|
||||
url="http://fabrice.bellard.free.fr/qemu/">QEMU</ulink> can run
|
||||
both Windows and ReactOS virtually. Other, commercial virtual
|
||||
machine offerings include <ulink
|
||||
url="http://www.vmware.com/">VMware</ulink> and Microsoft's
|
||||
<ulink url="http://www.microsoft.com/windowsxp/virtualpc/">VirtualPC</ulink>.
|
||||
</para>
|
||||
<para>
|
||||
There are significant drawbacks to using virtual machines,
|
||||
however. Unlike Wine, such programs <emphasis>are</emphasis>
|
||||
emulators, so there is an inevitable speed decrease which can
|
||||
be quite substantial. Furthermore, running an application
|
||||
inside a virtual machine prevents fully integrating the
|
||||
application within the current environment. You won't, for
|
||||
example, be able to have windows system tray icons or program
|
||||
shortcuts sitting alongside your desktop Linux ones, since
|
||||
instead the Windows applications must reside completely within
|
||||
the virtual machine.
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
||||
<!-- Keep this comment at the end of the file
|
||||
Local variables:
|
||||
mode: sgml
|
||||
sgml-parent-document:("wine-user.sgml" "set" "book" "chapter" "")
|
||||
End:
|
||||
-->
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,368 +0,0 @@
|
|||
<chapter id="opengl">
|
||||
<title>Wine and OpenGL</title>
|
||||
|
||||
<sect1 id="opengl-required">
|
||||
<title>What is needed to have OpenGL support in Wine</title>
|
||||
|
||||
<para>
|
||||
Basically, if you have a Linux OpenGL ABI compliant libGL
|
||||
(<ulink url="http://oss.sgi.com/projects/ogl-sample/ABI/">
|
||||
http://oss.sgi.com/projects/ogl-sample/ABI/</ulink>)
|
||||
installed on your computer, you should have everything
|
||||
that is needed.
|
||||
</para>
|
||||
<para>
|
||||
For clarity, I will detail one step after another what
|
||||
the <command>configure</command> script checks.
|
||||
</para>
|
||||
<para>
|
||||
If, after Wine compiles, OpenGL support is not compiled in,
|
||||
you can always check <filename>config.log</filename> to see
|
||||
which of the following points failed.
|
||||
</para>
|
||||
|
||||
<sect2>
|
||||
<title>Header files</title>
|
||||
|
||||
<para>
|
||||
The needed header files to build OpenGL support in Wine are :
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><filename>gl.h:</filename></term>
|
||||
<listitem>
|
||||
<para>
|
||||
the definition of all OpenGL core functions, types and enumerants
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><filename>glx.h:</filename></term>
|
||||
<listitem>
|
||||
<para>
|
||||
how OpenGL integrates in the X Window environment
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><filename>glext.h:</filename></term>
|
||||
<listitem>
|
||||
<para>
|
||||
the list of all registered OpenGL extensions
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<para>
|
||||
The latter file (<filename>glext.h</filename>) is, as of
|
||||
now, not necessary to build Wine. But as this file can be
|
||||
easily obtained from SGI
|
||||
(<ulink url="http://oss.sgi.com/projects/ogl-sample/ABI/glext.h">
|
||||
http://oss.sgi.com/projects/ogl-sample/ABI/glext.h</ulink>),
|
||||
and that all OpenGL should provide one, I decided to keep it here.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>OpenGL library itself</title>
|
||||
|
||||
<para>
|
||||
To check for the presence of 'libGL' on the system, the
|
||||
script checks if it defines the
|
||||
<function>glXCreateContext</function> function.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>glXGetProcAddressARB function</title>
|
||||
|
||||
<para>
|
||||
The core of Wine's OpenGL implementation (at least for all
|
||||
extensions) is the <function>glXGetProcAddressARB</function>
|
||||
function. Your OpenGL library needs to have this function
|
||||
defined for Wine to be able to support OpenGL.
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="opengl-works">
|
||||
<title>How it all works</title>
|
||||
|
||||
<para>
|
||||
The core OpenGL function calls are the same between Windows
|
||||
and Linux. So what is the difficulty to support it in Wine ?
|
||||
Well, there are two different problems :
|
||||
</para>
|
||||
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
the interface to the windowing system is different for
|
||||
each OS. It's called 'GLX' for Linux (well, for X Window)
|
||||
and 'wgl' for Windows. Thus, one need first to emulate one
|
||||
(wgl) with the other (GLX).
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
the calling convention between Windows (the 'Pascal'
|
||||
convention or 'stdcall') is different from the one used on
|
||||
Linux (the 'C' convention or 'cdecl'). This means that
|
||||
each call to an OpenGL function must be 'translated' and
|
||||
cannot be used directly by the Windows program.
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
|
||||
<para>
|
||||
Add to this some brain-dead programs (using GL calls without
|
||||
setting-up a context or deleting three time the same context)
|
||||
and you have still some work to do :-)
|
||||
</para>
|
||||
|
||||
<sect2>
|
||||
<title>The Windowing system integration</title>
|
||||
|
||||
<para>
|
||||
This integration is done at two levels :
|
||||
</para>
|
||||
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
At GDI level for all pixel format selection routines (ie
|
||||
choosing if one wants a depth / alpha buffer, the size
|
||||
of these buffers, ...) and to do the 'page flipping' in
|
||||
double buffer mode. This is implemented in
|
||||
<filename>dlls/x11drv/opengl.c</filename> (all these
|
||||
functions are part of Wine's graphic driver function
|
||||
pointer table and thus could be reimplemented if ever Wine
|
||||
works on another Windowing system than X).
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
In the <filename>OpenGL32.DLL</filename> itself for all
|
||||
other functionalities (context creation / deletion,
|
||||
querying of extension functions, ...). This is done in
|
||||
<filename>dlls/opengl32/wgl.c</filename>.
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>The thunks</title>
|
||||
|
||||
<para>
|
||||
The thunks are the Wine code that does the calling
|
||||
convention translation and they are auto-generated by a Perl
|
||||
script. In Wine's CVS tree, these thunks are already
|
||||
generated for you. Now, if you want to do it yourself, there
|
||||
is how it all works....
|
||||
</para>
|
||||
<para>
|
||||
The script is located in <filename>dlls/opengl32</filename>
|
||||
and is called <command>make_opengl</command>. It requires
|
||||
Perl5 to work and takes two arguments :
|
||||
</para>
|
||||
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
The first is the path to the OpenGL registry. Now, you
|
||||
will all ask 'but what is the OpenGL registry ?' :-)
|
||||
Well, it's part of the OpenGL sample implementation
|
||||
source tree from SGI (more informations at this URL :
|
||||
<ulink url="http://oss.sgi.com/projects/ogl-sample/">
|
||||
http://oss.sgi.com/projects/ogl-sample/</ulink>.
|
||||
</para>
|
||||
<para>
|
||||
To summarize, these files contain human-readable but
|
||||
easily parsed information on ALL OpenGL core functions
|
||||
and ALL registered extensions (for example the
|
||||
prototype, the OpenGL version, ...).
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
the second is the OpenGL version to 'simulate'. This
|
||||
fixes the list of functions that the Windows application
|
||||
can link directly to without having to query them from
|
||||
the OpenGL driver. Windows is based, for now, on OpenGL
|
||||
1.1, but the thunks that are in the CVS tree are
|
||||
generated for OpenGL 1.2.
|
||||
</para>
|
||||
<para>
|
||||
This option can have three values:
|
||||
<literal>1.0</literal>, <literal>1.1</literal> and
|
||||
<literal>1.2</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
|
||||
<para>
|
||||
This script generates three files :
|
||||
</para>
|
||||
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
<filename>opengl32.spec</filename> gives Wine's linker
|
||||
the signature of all function in the
|
||||
<filename>OpenGL32.DLL</filename> library so that the
|
||||
application can link them. Only 'core' functions are
|
||||
listed here.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<filename>opengl_norm.c</filename> contains all the
|
||||
thunks for the 'core' functions. Your OpenGL library
|
||||
must provide ALL the function used in this file as these
|
||||
are not queried at run time.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<filename>opengl_ext.c</filename> contains all the
|
||||
functions that are not part of the 'core' functions.
|
||||
Contrary to the thunks in
|
||||
<filename>opengl_norm.c</filename>, these functions do
|
||||
not depend at all on what your libGL provides.
|
||||
</para>
|
||||
<para>
|
||||
In fact, before using one of these thunks, the Windows
|
||||
program first needs to 'query' the function pointer. At
|
||||
this point, the corresponding thunk is useless. But as
|
||||
we first query the same function in libGL and store the
|
||||
returned function pointer in the thunk, the latter
|
||||
becomes functional.
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="opengl-problems">
|
||||
<title>Known problems</title>
|
||||
|
||||
<sect2>
|
||||
<title>When running an OpenGL application, the screen flickers</title>
|
||||
|
||||
<para>
|
||||
Due to restrictions (that do not exist in Windows) on OpenGL
|
||||
contexts, if you want to prevent the screen to flicker when
|
||||
using OpenGL applications (all games are using double-buffered
|
||||
contexts), you need to set the following option in your
|
||||
<filename>~/.wine/config</filename> file
|
||||
in the <literal>[x11drv]</literal> section:
|
||||
<programlisting>
|
||||
DesktopDoubleBuffered = Y
|
||||
</programlisting>
|
||||
and to run Wine in desktop mode.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Unknown extension error message:</title>
|
||||
|
||||
<screen>
|
||||
Extension defined in the OpenGL library but NOT in opengl_ext.c...
|
||||
Please report (lionel.ulmer@free.fr) !
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
This means that the extension requested by the application
|
||||
is found in the libGL used by Linux (ie the call to
|
||||
<function>glXGetProcAddressARB</function> returns a
|
||||
non-<constant>NULL</constant> pointer) but that this string
|
||||
was NOT found in Wine's extension registry.
|
||||
</para>
|
||||
<para>
|
||||
This can come from two causes:
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
The <filename>opengl_ext.c</filename> file is too old
|
||||
and needs to be generated again.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Use of obsolete extensions that are not supported
|
||||
anymore by SGI or of 'private' extensions that are not
|
||||
registered. An example of the former are
|
||||
<function>glMTexCoord2fSGIS</function> and
|
||||
<function>glSelectTextureSGIS</function> as used by
|
||||
Quake 2 (and apparently also by old versions of Half
|
||||
Life). If documentation can be found on these functions,
|
||||
they can be added to Wine's extension set.
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If you have this, run with <parameter>WINEDEBUG=+opengl</parameter>
|
||||
and send me <email>lionel.ulmer@free.fr</email> the TRACE.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title><filename>libopengl32.so</filename> is built but it is still not working</title>
|
||||
|
||||
<para>
|
||||
This may be caused by some missing functions required by
|
||||
<filename>opengl_norm.c</filename> but that your Linux
|
||||
OpenGL library does not provide.
|
||||
</para>
|
||||
<para>
|
||||
To check for this, do the following steps :
|
||||
</para>
|
||||
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
create a dummy <filename>.c</filename> file :
|
||||
</para>
|
||||
<programlisting>
|
||||
int main(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
</programlisting>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
try to compile it by linking both libwine and
|
||||
libopengl32 (this command line supposes that you
|
||||
installed the Wine libraries in
|
||||
<filename>/usr/local/lib</filename>, YMMV) :
|
||||
</para>
|
||||
<programlisting>
|
||||
gcc dummy.c -L/usr/local/lib -lwine -lopengl32
|
||||
</programlisting>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
if it works, the problem is somewhere else (and you can
|
||||
send me an email). If not, you could re-generate the
|
||||
thunk files for OpenGL 1.1 for example (and send me your
|
||||
OpenGL version so that this problem can be detected at
|
||||
configure time).
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
</sect2>
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
||||
<!-- Keep this comment at the end of the file
|
||||
Local variables:
|
||||
mode: sgml
|
||||
sgml-parent-document:("wine-devel.sgml" "set" "book" "part" "chapter" "")
|
||||
End:
|
||||
-->
|
|
@ -1,234 +0,0 @@
|
|||
<chapter id="patches">
|
||||
<title>Submitting Patches</title>
|
||||
|
||||
<sect1 id="patch-format">
|
||||
<title>Patch Format</title>
|
||||
|
||||
<para>
|
||||
Patches are submitted via email to the Wine patches mailing list,
|
||||
<email>wine-patches@winehq.org</email>. Your patch should include:
|
||||
</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
A meaningful subject (very short description of patch)
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
A long (paragraph) description of what was wrong and what is now
|
||||
better. (recommended)
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
A change log entry (short description of what was changed).
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The patch in <command>diff -u</command> format
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<command>cvs diff -u</command> works great for the common case
|
||||
where a file is edited. However, if you add or remove a file
|
||||
<command>cvs diff</command> will not report that correctly so
|
||||
make sure you explicitly take care of this rare case.
|
||||
</para>
|
||||
<para>
|
||||
For additions simply include them by appending the
|
||||
<command>diff -u /dev/null /my/new/file</command> output of them
|
||||
to any <command>cvs diff -u</command> output you may have.
|
||||
Alternatively, use <command>diff -Nu olddir/ newdir/</command>
|
||||
in case of multiple new files to add.
|
||||
</para>
|
||||
<para>
|
||||
For removals, clearly list the files in the description of the patch.
|
||||
</para>
|
||||
<para>
|
||||
Since wine is constantly changing due to development it is strongly
|
||||
recommended that you use cvs for patches, if you cannot use cvs for
|
||||
some reason, you can submit patches against the latest tarball.
|
||||
To do this make a copy of the files that you will be modifying and
|
||||
<command>diff -u</command> against the old file. I.E.
|
||||
</para>
|
||||
<screen>
|
||||
diff -u file.old file.c > file.txt
|
||||
</screen>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="Style-notes">
|
||||
<title>Some notes about style</title>
|
||||
|
||||
<para>
|
||||
There are a few conventions that about coding style that have been
|
||||
adopted over the years of development. The rational for these
|
||||
<quote>rules</quote> is explained for each one.
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
No HTML mail, since patches should be in-lined and HTML turns the
|
||||
patch into garbage. Also it is considered bad etiquette as it
|
||||
uglifies the message, and is not viewable by many of the subscribers.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Only one change set per patch. Patches should address only one
|
||||
bug/problem at a time. If a lot of changes need to be made then it
|
||||
is preferred to break it into a series of patches. This makes it
|
||||
easier to find regressions.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Tabs are not forbidden but discouraged. A tab is defined as
|
||||
8 characters and the usual amount of indentation is 4
|
||||
characters.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
C++ style comments are discouraged since some compilers choke on
|
||||
them.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Commenting out a block of code is usually done by enclosing it in
|
||||
<command>#if 0 ... #endif</command> Statements. For example.
|
||||
</para>
|
||||
<screen>
|
||||
/* note about reason for commenting block */
|
||||
#if 0
|
||||
code
|
||||
code /* comments */
|
||||
code
|
||||
#endif
|
||||
</screen>
|
||||
<para>
|
||||
The reason for using this method is that it does not require that
|
||||
you edit comments that may be inside the block of code.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Patches should be in-lined (if you can configure your email client to
|
||||
not wrap lines), or attached as plain text attachments so they can
|
||||
be read inline. This may mean some more work for you. However it
|
||||
allows others to review your patch easily and decreases the chances
|
||||
of it being overlooked or forgotten.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Code is usually limited to 80 columns. This helps prevent mailers
|
||||
mangling patches by line wrap. Also it generally makes code easier
|
||||
to read.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
If the patch fixes a bug in Bugzilla please provide a link to the
|
||||
bug in the comments of the patch. This will make it easier for the
|
||||
maintainers of Bugzilla.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<sect2 id="Inline-Attachments-with-OE">
|
||||
<title>Inline attachments with Outlook Express</title>
|
||||
<para>
|
||||
Outlook Express is notorious for mangling attachments. Giving the
|
||||
patch a <filename>.txt</filename> extension and attaching will solve
|
||||
the problem for most mailers including Outlook. Also, there is a way
|
||||
to enable Outlook Express send <filename>.diff</filename>
|
||||
attachments.
|
||||
</para>
|
||||
<para>
|
||||
You need following two things to make it work.
|
||||
</para>
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
Make sure that <filename>.diff</filename> files have \r\n line
|
||||
ends, because if OE detects that there is no \r\n line endings it
|
||||
switches to quoted-printable format attachments.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Using regedit add key "Content Type" with value "text/plain"
|
||||
to the .diff extension under HKEY_CLASSES_ROOT (same as for .txt
|
||||
extension). This tells OE to use Content-Type: text/plain instead
|
||||
of application/octet-stream.
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
<para>
|
||||
Item #1 is important. After you hit "Send" button, go to "Outbox"
|
||||
and using "Properties" verify the message source to make sure that
|
||||
the mail has correct format. You might want to send several test
|
||||
emails to yourself too.
|
||||
</para>
|
||||
</sect2>
|
||||
<sect2 id="Alexandre-Bottom-Line">
|
||||
<title>Alexandre's Bottom Line</title>
|
||||
<para>
|
||||
<quote>The basic rules are: no attachments, no mime crap, no
|
||||
line wrapping, a single patch per mail. Basically if I can't
|
||||
do <command>"cat raw_mail | patch -p0"</command> it's in the
|
||||
wrong format.</quote>
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="patch-quality">
|
||||
<title>Quality Assurance</title>
|
||||
|
||||
<para>
|
||||
(Or, "How do I get Alexandre to apply my patch quickly so I
|
||||
can build on it and it will not go stale?")
|
||||
</para>
|
||||
<para>
|
||||
Make sure your patch applies to the current CVS head
|
||||
revisions. If a bunch of patches are committed to CVS that may
|
||||
affect whether your patch will apply cleanly then verify that
|
||||
your patch does apply! <command>cvs update</command> is your
|
||||
friend!
|
||||
</para>
|
||||
<para>
|
||||
Try to test your patch against more than just your current test
|
||||
example. Experience will tell you how much effort to apply here.
|
||||
If there are any conformance tests for the code you're working on,
|
||||
run them and make sure they still pass after your patch is applied.
|
||||
Running tests can be done by running <command>make test</command>.
|
||||
You may need to run <command>make testclean</command> to undo the
|
||||
results of a previous test run.
|
||||
</para>
|
||||
<para>
|
||||
Please consider submitting a conformance test for your changes.
|
||||
This will make it a lot clearer for everyone that your patch is
|
||||
needed, and it will prevent future breakage. While you are not
|
||||
strictly required to submit tests, it is highly encouraged to do so.
|
||||
See the <quote>testing</quote> guide for more details on Wine's
|
||||
conformance tests.
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
||||
<!-- Keep this comment at the end of the file
|
||||
Local variables:
|
||||
mode: sgml
|
||||
sgml-parent-document:("wine-devel.sgml" "set" "book" "part" "chapter" "")
|
||||
End:
|
||||
-->
|
|
@ -1,214 +0,0 @@
|
|||
<sect1 id="config-printing">
|
||||
<title>Printing in Wine</title>
|
||||
<para>How to print documents in Wine...</para>
|
||||
|
||||
<sect2 id="config-printing-intro">
|
||||
<title>Printing</title>
|
||||
|
||||
<para>
|
||||
Printing in Wine can be done using the built-in Wine PostScript driver (+ ghostscript to produce
|
||||
output for non-PostScript printers).
|
||||
</para>
|
||||
<para>
|
||||
Note that at the moment WinPrinters (cheap, dumb printers that require
|
||||
the host computer to explicitly control the head) will not work with
|
||||
their Windows printer drivers. It is unclear whether they ever will.
|
||||
</para>
|
||||
|
||||
<sect3>
|
||||
<title>Built-in Wine PostScript driver</title>
|
||||
<para>
|
||||
Enables printing of PostScript files via a driver built into Wine. See
|
||||
below for installation instructions. The code for the PostScript
|
||||
driver is in <filename>dlls/wineps/</filename>.
|
||||
</para>
|
||||
<para>
|
||||
The driver behaves as if it were a DRV file called
|
||||
<filename>wineps.drv</filename> which at the moment is built into
|
||||
Wine.
|
||||
Although it mimics a 16 bit driver, it will work with both 16 and 32
|
||||
bit apps, just as win9x drivers do.
|
||||
</para>
|
||||
</sect3>
|
||||
|
||||
<sect3>
|
||||
<title>Spooling</title>
|
||||
<para>
|
||||
Spooling is rather primitive. The [spooler] section of
|
||||
the wine config file maps a port (e.g.
|
||||
<systemitem>LPT1:</systemitem>) to a file or a command via a pipe. For
|
||||
example the following lines
|
||||
</para>
|
||||
<screen>
|
||||
"LPT1:" = "foo.ps"
|
||||
"LPT2:" = "|lpr"
|
||||
</screen>
|
||||
<para>
|
||||
map <systemitem>LPT1:</systemitem> to file <filename>foo.ps</filename>
|
||||
and <systemitem>LPT2:</systemitem> to the <command>lpr</command>
|
||||
command. If a job is sent to an unlisted port, then a file is created
|
||||
with that port's name; e.g. for <systemitem>LPT3:</systemitem> a file
|
||||
called <systemitem>LPT3:</systemitem> would be created.
|
||||
</para>
|
||||
<para>
|
||||
There are now also virtual spool queues called
|
||||
<systemitem>LPR:printername</systemitem>, which send the data
|
||||
to <command>lpr -Pprintername</command>. You do not need to
|
||||
specify those in the config file, they are handled automatically by
|
||||
<filename>dlls/gdi/printdrv.c</filename>.
|
||||
</para>
|
||||
</sect3>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="config-printing-psdriver">
|
||||
<title>The Wine PostScript Driver</title>
|
||||
|
||||
<para>
|
||||
This allows Wine to generate PostScript files without
|
||||
needing an external printer driver. Wine in this case uses the
|
||||
system provided PostScript printer filters, which almost all use
|
||||
ghostscript if necessary. Those should be configured during the
|
||||
original system installation or by your system administrator.
|
||||
</para>
|
||||
|
||||
<sect3>
|
||||
<title>Installation</title>
|
||||
<sect4>
|
||||
<title>Installation of CUPS printers</title>
|
||||
<para>
|
||||
If you are using CUPS, you do not need to configure .ini or
|
||||
registry entries, everything is autodetected.
|
||||
</para>
|
||||
</sect4>
|
||||
<sect4>
|
||||
<title>Installation of LPR /etc/printcap based printers</title>
|
||||
<para>
|
||||
If your system is not yet using CUPS, it probably uses LPRng
|
||||
or a LPR based system with configuration based on <filename>/etc/printcap</filename>.
|
||||
</para>
|
||||
<para>
|
||||
If it does, your printers in <filename>/etc/printcap</filename>
|
||||
are scanned with a heuristic whether they are PostScript capable
|
||||
printers and also configured mostly automatic.
|
||||
</para>
|
||||
<para>
|
||||
Since Wine cannot find out what type of printer this is, you
|
||||
need to specify a PPD file in the [ppd] section of
|
||||
<filename>~/.wine/config</filename>. Either use the shortcut
|
||||
name and make the entry look like:
|
||||
</para>
|
||||
<screen>
|
||||
[ppd]
|
||||
"ps1" = "/usr/lib/wine/ps1.ppd"
|
||||
</screen>
|
||||
<para>
|
||||
Or you can specify a generic PPD file that is to match for all
|
||||
of the remaining printers. A generic PPD file can be found in
|
||||
<filename>documentation/samples/generic.ppd</filename>.
|
||||
</para>
|
||||
</sect4>
|
||||
<sect4>
|
||||
<title>Installation of other printers</title>
|
||||
<para>
|
||||
You do not need to do this if the above 2 sections apply, only if
|
||||
you have a special printer.
|
||||
</para>
|
||||
<screen>
|
||||
Wine PostScript Driver=WINEPS,LPT1:
|
||||
</screen>
|
||||
<para>
|
||||
to the [devices] section and
|
||||
</para>
|
||||
<screen>
|
||||
Wine PostScript Driver=WINEPS,LPT1:,15,45
|
||||
</screen>
|
||||
<para>
|
||||
to the [PrinterPorts] section of <filename>win.ini</filename>,
|
||||
and to set it as the default printer also add
|
||||
</para>
|
||||
<screen>
|
||||
device = Wine PostScript Driver,WINEPS,LPT1:
|
||||
</screen>
|
||||
<para>
|
||||
to the [windows] section of <filename>win.ini</filename>.
|
||||
</para>
|
||||
<para>
|
||||
You also need to add certain entries to the registry.
|
||||
The easiest way to do this is to customize the PostScript
|
||||
driver contents of <filename>wine.inf</filename> (see below) and use the
|
||||
Winelib program <command>programs/regedit/regedit</command>. For
|
||||
example, if you have installed the Wine source tree in
|
||||
<filename>/usr/src/wine</filename>, you could use the following
|
||||
series of commands:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
<userinput>#vi /usr/share/wine/wine.inf</userinput>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Edit the copy of <filename>wine.inf</filename> to suit your
|
||||
PostScript printing requirements.
|
||||
At a minimum, you must specify a PPD file for each printer.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<userinput>$wineprefixcreate</userinput>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</sect4>
|
||||
<sect4>
|
||||
<title>Required configuration for all printer types</title>
|
||||
<para>
|
||||
You won't need Adobe Font Metric (AFM) files for the (type 1 PostScript)
|
||||
fonts that you wish to use any more.
|
||||
Wine now has this information built-in.
|
||||
</para>
|
||||
<para>
|
||||
You'll need a PPD file for your printer. This describes
|
||||
certain characteristics of the printer such as which fonts are
|
||||
installed, how to select manual feed etc. Adobe has many of
|
||||
these on its website, have a look in
|
||||
<ulink url="ftp://ftp.adobe.com/pub/adobe/printerdrivers/win/all/">
|
||||
ftp://ftp.adobe.com/pub/adobe/printerdrivers/win/all/</ulink>.
|
||||
See above for information on configuring the driver to use this
|
||||
file.
|
||||
</para>
|
||||
<para>
|
||||
To enable colour printing you need to have the
|
||||
<literal>*ColorDevice</literal> entry in the PPD set to
|
||||
<literal>true</literal>, otherwise the driver will generate
|
||||
greyscale.
|
||||
</para>
|
||||
<para>
|
||||
Note that you need not set <literal>printer=on</literal> in
|
||||
the [wine] section of the wine config file, this
|
||||
enables printing via external printer drivers and does not
|
||||
affect the built-in PostScript driver.
|
||||
</para>
|
||||
<para>
|
||||
If you're lucky you should now be able to produce PS files
|
||||
from Wine!
|
||||
</para>
|
||||
<para>
|
||||
I've tested it with win3.1 notepad/write, Winword6 and
|
||||
Origin4.0 and 32 bit apps such as win98 wordpad, Winword97,
|
||||
Powerpoint2000 with some degree of success - you should be
|
||||
able to get something out, it may not be in the right place.
|
||||
</para>
|
||||
</sect4>
|
||||
</sect3>
|
||||
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<!-- Keep this comment at the end of the file
|
||||
Local variables:
|
||||
mode: sgml
|
||||
sgml-parent-document:("wine-user.sgml" "set" "book" "chapter" "")
|
||||
End:
|
||||
-->
|
|
@ -1,359 +0,0 @@
|
|||
<sect1 id="registry">
|
||||
<title>The Registry</title>
|
||||
|
||||
<para>
|
||||
After Win3.x, the registry became a fundamental part of Windows.
|
||||
It is the place where both Windows itself, and all
|
||||
Win95/98/NT/2000/XP/etc.-compliant applications, store
|
||||
configuration and state data. While most sane system
|
||||
administrators (and Wine developers) curse badly at the twisted
|
||||
nature of the Windows registry, it is still necessary for Wine
|
||||
to support it somehow.
|
||||
</para>
|
||||
|
||||
<sect2>
|
||||
<title>The default registry</title>
|
||||
|
||||
<para>
|
||||
A Windows registry contains many keys by default, and some of
|
||||
them are necessary for even installers to operate correctly.
|
||||
The keys that the Wine developers have found necessary to
|
||||
install applications are distributed in a file called
|
||||
<filename>wine.inf</filename>. It is automatically
|
||||
installed for you if you use the
|
||||
<filename>tools/wineinstall</filename> script in the Wine source,
|
||||
but if you want to install it manually, you can do so by using the
|
||||
<command>regedit</command> tool to be found in the
|
||||
<filename>programs/regedit/</filename>
|
||||
directory in Wine source.
|
||||
<filename>wine.inf</filename> is applied even if
|
||||
you plan to use a native Windows registry, since Wine needs some
|
||||
specific registry settings in its registry (for special
|
||||
workarounds for certain programs etc.).
|
||||
This is done automatically by wine the first time you run it.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Using a Windows registry</title>
|
||||
|
||||
<para>
|
||||
If you point Wine at an existing Windows installation (by
|
||||
setting the appropriate directories in
|
||||
<filename>~/.wine/config</filename>, then Wine is able to load
|
||||
registry data from it. However, Wine will not save anything to
|
||||
the real Windows registry, but rather to its own registry
|
||||
files (see below). Of course, if a particular registry value
|
||||
exists in both the Windows registry and in the Wine registry,
|
||||
then Wine will use the latter. In the Wine config file, there
|
||||
are a number of configuration settings in the [registry] section
|
||||
(see below) specific to the handling of Windows registry content by Wine.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>The Registry</title>
|
||||
<para>
|
||||
The initial default registry content to be used by the Wine
|
||||
registry files is in the file
|
||||
<filename>wine.inf</filename>. It contains directory
|
||||
paths, class IDs, and more; it must be installed before most
|
||||
<filename>INSTALL.EXE</filename> or
|
||||
<filename>SETUP.EXE</filename> applications will work.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Registry structure</title>
|
||||
|
||||
<para>
|
||||
The Windows registry is an elaborate tree structure, and not
|
||||
even most Windows programmers are fully aware of how the
|
||||
registry is laid out, with its different "hives" and numerous
|
||||
links between them; a full coverage is out of the scope of
|
||||
this document. But here are the basic registry keys you might
|
||||
need to know about for now.
|
||||
</para>
|
||||
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>HKEY_LOCAL_MACHINE</term>
|
||||
<listitem>
|
||||
<para>
|
||||
This fundamental root key (in win9x it's stored in the
|
||||
hidden file <filename>system.dat</filename>) contains
|
||||
everything pertaining to the current Windows
|
||||
installation.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>HKEY_USERS</term>
|
||||
<listitem>
|
||||
<para>
|
||||
This fundamental root key (in win9x it's stored in the
|
||||
hidden file <filename>user.dat</filename>) contains
|
||||
configuration data for every user of the installation.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>HKEY_CLASSES_ROOT</term>
|
||||
<listitem>
|
||||
<para>
|
||||
This is a link to HKEY_LOCAL_MACHINE\Software\Classes.
|
||||
It contains data describing things like file
|
||||
associations, OLE document handlers, and COM classes.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>HKEY_CURRENT_USER</term>
|
||||
<listitem>
|
||||
<para>
|
||||
This is a link to HKEY_USERS\your_username, i.e., your
|
||||
personal configuration.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Wine registry data files</title>
|
||||
|
||||
<para>
|
||||
In the user's home directory, there is a subdirectory named
|
||||
<filename>.wine</filename>, where Wine will try to save its
|
||||
registry by default. It saves into four files, which are:
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><filename>system.reg</filename></term>
|
||||
<listitem>
|
||||
<para>
|
||||
This file contains HKEY_LOCAL_MACHINE.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><filename>user.reg</filename></term>
|
||||
<listitem>
|
||||
<para>
|
||||
This file contains HKEY_CURRENT_USER.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><filename>userdef.reg</filename></term>
|
||||
<listitem>
|
||||
<para>
|
||||
This file contains HKEY_USERS\.Default (i.e. the default
|
||||
user settings).
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><filename>wine.userreg</filename></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Wine saves HKEY_USERS to this file (both current and
|
||||
default user), but does not load from it, unless
|
||||
<filename>userdef.reg</filename> is missing.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
<para>
|
||||
All of these files are human-readable text files, so unlike
|
||||
Windows, you can actually use an ordinary text editor on them
|
||||
if you want (make sure you don't have Wine running when modifying
|
||||
them, otherwise your changes will be discarded).
|
||||
</para>
|
||||
<para>
|
||||
FIXME: global configuration currently not implemented.
|
||||
|
||||
In addition to these files, Wine can also optionally load from
|
||||
global registry files residing in the same directory as the
|
||||
global <filename>wine.conf</filename> (i.e.
|
||||
<filename>/usr/local/etc</filename> if you compiled from
|
||||
source). These are:
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><filename>wine.systemreg</filename></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Contains HKEY_LOCAL_MACHINE.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><filename>wine.userreg</filename></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Contains HKEY_USERS.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>System administration</title>
|
||||
|
||||
<para>
|
||||
With the above file structure, it is possible for a system
|
||||
administrator to configure the system so that a system Wine
|
||||
installation (and applications) can be shared by all the
|
||||
users, and still let the users all have their own personalized
|
||||
configuration. An administrator can, after having installed
|
||||
Wine and any Windows application software he wants the users
|
||||
to have access to, copy the resulting
|
||||
<filename>system.reg</filename> and
|
||||
<filename>user.reg</filename> over to the global registry
|
||||
files (which we assume will reside in
|
||||
<filename>/usr/local/etc</filename> here), with:
|
||||
</para>
|
||||
<screen>
|
||||
cd ~/.wine
|
||||
cp system.reg /usr/local/etc/wine.systemreg
|
||||
cp user.reg /usr/local/etc/wine.userreg
|
||||
</screen>
|
||||
<para>
|
||||
and perhaps even symlink these back to the administrator's
|
||||
account, to make it easier to install apps system-wide later:
|
||||
</para>
|
||||
<screen>
|
||||
ln -sf /usr/local/etc/wine.systemreg system.reg
|
||||
ln -sf /usr/local/etc/wine.userreg user.reg
|
||||
</screen>
|
||||
<para>
|
||||
Note that the <filename>tools/wineinstall</filename> script
|
||||
already does all of this for you, if you install Wine source as root.
|
||||
If you then install Windows applications while logged in as
|
||||
root, all your users will automatically be able to use them.
|
||||
While the application setup will be taken from the global
|
||||
registry, the users' personalized configurations will be saved
|
||||
in their own home directories.
|
||||
</para>
|
||||
<para>
|
||||
But be careful with what you do with the administrator account
|
||||
- if you do copy or link the administrator's registry to the
|
||||
global registry, any user might be able to read the
|
||||
administrator's preferences, which might not be good if
|
||||
sensitive information (passwords, personal information, etc)
|
||||
is stored there. Only use the administrator account to install
|
||||
software, not for daily work; use an ordinary user account for
|
||||
that.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>The [registry] section</title>
|
||||
|
||||
<para>
|
||||
Now let's look at the <link linkend="config-file">Wine
|
||||
configuration file</link> options for handling the registry.
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>GlobalRegistryDir</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Optional. Sets the path to look for the Global
|
||||
Registry.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>LoadGlobalRegistryFiles</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Controls whether to try to load the global registry
|
||||
files, if they exist.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>LoadHomeRegistryFiles</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Controls whether to try to load the user's registry
|
||||
files (in the <filename>.wine</filename> subdirectory of
|
||||
the user's home directory).
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>LoadWindowsRegistryFiles</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Controls whether Wine will attempt to load registry data
|
||||
from a real Windows registry in an existing MS Windows
|
||||
installation.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>WritetoHomeRegistryFiles</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Controls whether registry data will be written to the
|
||||
user's registry files. (Currently, there is no
|
||||
alternative, so if you turn this off, Wine cannot save
|
||||
the registry on disk at all; after you exit Wine, your
|
||||
changes will be lost.)
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>SaveOnlyUpdatedKeys</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Controls whether the entire registry is saved to the
|
||||
user's registry files, or only subkeys the user have
|
||||
actually changed. Considering that the user's registry
|
||||
will override any global registry files and Windows
|
||||
registry files, it usually makes sense to only save
|
||||
user-modified subkeys; that way, changes to the rest of
|
||||
the global or Windows registries will still affect the
|
||||
user.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>PeriodicSave</term>
|
||||
<listitem>
|
||||
<para>
|
||||
If this option is set to a nonzero value, it specifies
|
||||
that you want the registry to be saved to disk at the
|
||||
given interval. If it is not set, the registry will only
|
||||
be saved to disk when the wineserver terminates.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>UseNewFormat</term>
|
||||
<listitem>
|
||||
<para>
|
||||
This option is obsolete. Wine now always uses the new
|
||||
format; support for the old format was removed a while
|
||||
ago.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<!-- Keep this comment at the end of the file
|
||||
Local variables:
|
||||
mode: sgml
|
||||
sgml-parent-document:("configuring.sgml" "chapter" "sect1" "")
|
||||
End:
|
||||
-->
|
|
@ -1,717 +0,0 @@
|
|||
<chapter id="running">
|
||||
<title>Running Wine</title>
|
||||
|
||||
<para>
|
||||
This chapter will describe all aspects of running Wine, like e.g.
|
||||
basic Wine invocation, command line parameters of various Wine
|
||||
support programs etc.
|
||||
</para>
|
||||
|
||||
<sect1 id="basic-usage">
|
||||
<title>Basic usage: applications and control panel applets</title>
|
||||
<para>
|
||||
Assuming you are using a fake Windows installation, you install
|
||||
applications into Wine in the same way you would in Windows: by
|
||||
running the installer. You can just accept the defaults for
|
||||
where to install, most installers will default to "C:\Program
|
||||
Files", which is fine. If the application installer requests it,
|
||||
you may find that Wine creates icons on your desktop and in your
|
||||
app menu. If that happens, you can start the app by clicking on
|
||||
them.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The standard way to uninstall things is for the application to
|
||||
provide an uninstaller, usually registered with the "Add/Remove
|
||||
Programs" control panel applet.
|
||||
To access the Wine equivalent, run the <command>uninstaller</command>
|
||||
program (it is located in the
|
||||
<filename>programs/uninstaller/</filename> directory in a Wine
|
||||
source directory) in a <glossterm>terminal</glossterm>:
|
||||
</para>
|
||||
|
||||
<screen>
|
||||
<prompt>$</prompt> <userinput>uninstaller</userinput>
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
Some programs install associated control panel applets, examples
|
||||
of this would be Internet Explorer and QuickTime. You can access
|
||||
the Wine control panel by running in a
|
||||
<glossterm>terminal</glossterm>:
|
||||
</para>
|
||||
|
||||
<screen>
|
||||
<prompt>$</prompt> <userinput>wine control</userinput>
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
which will open a window with the installed control panel
|
||||
applets in it, as in Windows.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If the application doesn't install menu or desktop items, you'll
|
||||
need to run the app from the command line. Remembering where you
|
||||
installed to, something like:
|
||||
</para>
|
||||
|
||||
<screen>
|
||||
<prompt>$</prompt> <userinput>wine "c:\program files\appname\appname.exe"</userinput>
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
will probably do the trick. The path isn't case sensitive, but
|
||||
remember to include the double quotes. Some programs don't
|
||||
always use obvious naming for their directories and EXE files,
|
||||
so you might have to look inside the program files directory to
|
||||
see what was put where.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="running-wine">
|
||||
<title>How to run Wine</title>
|
||||
|
||||
<para>
|
||||
You can simply invoke the <command>wine</command> command to
|
||||
get a small help message:
|
||||
</para>
|
||||
<para>
|
||||
<screen>
|
||||
Wine 20040405
|
||||
Usage: wine PROGRAM [ARGUMENTS...] Run the specified program
|
||||
wine --help Display this help and exit
|
||||
wine --version Output version information and exit
|
||||
</screen>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The first argument should be the name of the file you
|
||||
want <command>wine</command> to execute. If the executable is
|
||||
in the <parameter>Path</parameter> environment variable, you can
|
||||
simply give the executable file name. However, if the executable
|
||||
is not in <parameter>Path</parameter>, you must give the full path to
|
||||
the executable (in Windows format, not UNIX format!). For
|
||||
example, given a <parameter>Path</parameter> of the following:
|
||||
</para>
|
||||
<screen>
|
||||
Path="c:\windows;c:\windows\system;e:\;e:\test;f:\"
|
||||
</screen>
|
||||
<para>
|
||||
You could run the file
|
||||
<filename>c:\windows\system\foo.exe</filename> with:
|
||||
</para>
|
||||
<screen>
|
||||
<prompt>$</prompt> <userinput>wine foo.exe</userinput>
|
||||
</screen>
|
||||
<para>
|
||||
However, you would have to run the file
|
||||
<filename>c:\myapps\foo.exe</filename> with this command:
|
||||
</para>
|
||||
<screen>
|
||||
<prompt>$</prompt> <userinput>wine c:\\myapps\\foo.exe</userinput>
|
||||
</screen>
|
||||
<para>
|
||||
(note the backslash-escaped "\" !)
|
||||
</para>
|
||||
<para>
|
||||
For details on running text mode (CUI) executables, read the
|
||||
<link linkend="CUI-programs">section</link> below.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="explorer-like-wine">
|
||||
<title>Explorer-like graphical Wine environments</title>
|
||||
|
||||
<para>
|
||||
If you prefer using a graphical interface to manage your
|
||||
files you might want to consider using Winefile. This Winelib
|
||||
application comes with Wine and can be found with the other
|
||||
Wine programs. It is a useful way to view your drive configuration
|
||||
and locate files, plus you can execute programs directly from
|
||||
Winefile. Please note, many functions are not yet implemented.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="command-line-options">
|
||||
<title>Wine Command Line Options</title>
|
||||
|
||||
<sect2>
|
||||
<title>--help</title>
|
||||
<para>
|
||||
Shows a small command line help page.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>--version</title>
|
||||
<para>
|
||||
Shows the Wine version string. Useful to verify your installation.
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Environment variables</title>
|
||||
<sect2>
|
||||
<title>WINEDEBUG=[channels]</title>
|
||||
<para>
|
||||
Wine isn't perfect, and many Windows applications still
|
||||
don't run without bugs under Wine (but then, a lot of programs
|
||||
don't run without bugs under native Windows either!). To
|
||||
make it easier for people to track down the causes behind
|
||||
each bug, Wine provides a number of <firstterm>debug
|
||||
channels</firstterm> that you can tap into.
|
||||
</para>
|
||||
<para>
|
||||
Each debug channel, when activated, will trigger logging
|
||||
messages to be displayed to the console where you invoked
|
||||
<command>wine</command>. From there you can redirect the
|
||||
messages to a file and examine it at your leisure. But be
|
||||
forewarned! Some debug channels can generate incredible
|
||||
volumes of log messages. Among the most prolific offenders
|
||||
are <parameter>relay</parameter> which spits out a log
|
||||
message every time a win32 function is called,
|
||||
<parameter>win</parameter> which tracks windows message
|
||||
passing, and of course <parameter>all</parameter> which is
|
||||
an alias for every single debug channel that exists. For a
|
||||
complex application, your debug logs can easily top 1 MB and
|
||||
higher. A <parameter>relay</parameter> trace can often
|
||||
generate more than 10 MB of log messages, depending on how
|
||||
long you run the application. (As described in the
|
||||
<link linkend = "config-debug-etc">Debug</link>
|
||||
section of configuring wine you can
|
||||
modify what the <parameter>relay</parameter> trace reports).
|
||||
Logging does slow down Wine
|
||||
quite a bit, so don't use <parameter>WINEDEBUG</parameter>
|
||||
unless you really do want log files.
|
||||
</para>
|
||||
<para>
|
||||
Within each debug channel, you can further specify a
|
||||
<firstterm>message class</firstterm>, to filter out the
|
||||
different severities of errors. The four message classes
|
||||
are:
|
||||
<simplelist type="inline">
|
||||
<member><parameter>trace</parameter></member>
|
||||
<member><parameter>fixme</parameter></member>
|
||||
<member><parameter>warn</parameter></member>
|
||||
<member><parameter>err</parameter></member>
|
||||
</simplelist>.
|
||||
</para>
|
||||
<para>
|
||||
To turn on a debug channel, use the form
|
||||
<parameter>class+channel</parameter>. To turn it off, use
|
||||
<parameter>class-channel</parameter>. To list more than one
|
||||
channel in the same <parameter>WINEDEBUG</parameter>
|
||||
option, separate them with commas. For example, to request
|
||||
<parameter>warn</parameter> class messages in the
|
||||
<parameter>heap</parameter> debug channel, you could invoke
|
||||
<command>wine</command> like this:
|
||||
</para>
|
||||
<screen>
|
||||
<prompt>$</prompt> <userinput>WINEDEBUG=warn+heap wine <replaceable>program_name</replaceable></userinput>
|
||||
</screen>
|
||||
<para>
|
||||
If you leave off the message class, <command>wine</command>
|
||||
will display messages from all four classes for that channel:
|
||||
</para>
|
||||
<screen>
|
||||
<prompt>$</prompt> <userinput>WINEDEBUG=heap wine <replaceable>program_name</replaceable></userinput>
|
||||
</screen>
|
||||
<para>
|
||||
If you wanted to see log messages for everything except the
|
||||
relay channel, you might do something like this:
|
||||
</para>
|
||||
<screen>
|
||||
<prompt>$</prompt> <userinput>WINEDEBUG=+all,-relay wine <replaceable>program_name</replaceable></userinput>
|
||||
</screen>
|
||||
<para>
|
||||
Here is a list of the debug channels and classes in Wine.
|
||||
More channels will be added to (or subtracted from) later
|
||||
versions.
|
||||
</para>
|
||||
|
||||
<table frame="none"><title>Debug Channels</title>
|
||||
<tgroup cols=5 align="left">
|
||||
<tbody>
|
||||
<row> <entry>accel</entry> <entry>adpcm</entry> <entry>advapi</entry> <entry>animate</entry> <entry>aspi</entry> </row>
|
||||
<row> <entry>atom</entry> <entry>avicap</entry> <entry>avifile</entry> <entry>bidi</entry> <entry>bitblt</entry> </row>
|
||||
<row> <entry>bitmap</entry> <entry>cabinet</entry> <entry>capi</entry> <entry>caret</entry> <entry>cdrom</entry> </row>
|
||||
<row> <entry>cfgmgr32</entry> <entry>class</entry> <entry>clipboard</entry> <entry>clipping</entry> <entry>combo</entry> </row>
|
||||
<row> <entry>comboex</entry> <entry>comm</entry> <entry>commctrl</entry> <entry>commdlg</entry> <entry>computername</entry> </row>
|
||||
<row> <entry>console</entry> <entry>crtdll</entry> <entry>crypt</entry> <entry>curses</entry> <entry>cursor</entry> </row>
|
||||
<row> <entry>d3d</entry> <entry>d3d_shader</entry> <entry>d3d_surface</entry> <entry>datetime</entry> <entry>dc</entry> </row>
|
||||
<row> <entry>ddeml</entry> <entry>ddraw</entry> <entry>ddraw_fps</entry> <entry>ddraw_geom</entry> <entry>ddraw_tex</entry> </row>
|
||||
<row> <entry>debugstr</entry> <entry>devenum</entry> <entry>dialog</entry> <entry>dinput</entry> <entry>dll</entry> </row>
|
||||
<row> <entry>dma</entry> <entry>dmband</entry> <entry>dmcompos</entry> <entry>dmfile</entry> <entry>dmfiledat</entry> </row>
|
||||
<row> <entry>dmime</entry> <entry>dmloader</entry> <entry>dmscript</entry> <entry>dmstyle</entry> <entry>dmsynth</entry> </row>
|
||||
<row> <entry>dmusic</entry> <entry>dosfs</entry> <entry>dosmem</entry> <entry>dplay</entry> <entry>dplayx</entry> </row>
|
||||
<row> <entry>dpnhpast</entry> <entry>driver</entry> <entry>dsound</entry> <entry>dsound3d</entry> <entry>edit</entry> </row>
|
||||
<row> <entry>enhmetafile</entry> <entry>environ</entry> <entry>event</entry> <entry>eventlog</entry> <entry>exec</entry> </row>
|
||||
<row> <entry>file</entry> <entry>fixup</entry> <entry>font</entry> <entry>fps</entry> <entry>g711</entry> </row>
|
||||
<row> <entry>gdi</entry> <entry>global</entry> <entry>glu</entry> <entry>graphics</entry> <entry>header</entry> </row>
|
||||
<row> <entry>heap</entry> <entry>hook</entry> <entry>hotkey</entry> <entry>icmp</entry> <entry>icon</entry> </row>
|
||||
<row> <entry>imagehlp</entry> <entry>imagelist</entry> <entry>imm</entry> <entry>int</entry> <entry>int21</entry> </row>
|
||||
<row> <entry>int31</entry> <entry>io</entry> <entry>ipaddress</entry> <entry>iphlpapi</entry> <entry>jack</entry> </row>
|
||||
<row> <entry>joystick</entry> <entry>key</entry> <entry>keyboard</entry> <entry>listbox</entry> <entry>listview</entry> </row>
|
||||
<row> <entry>loaddll</entry> <entry>local</entry> <entry>mapi</entry> <entry>mci</entry> <entry>mcianim</entry> </row>
|
||||
<row> <entry>mciavi</entry> <entry>mcicda</entry> <entry>mcimidi</entry> <entry>mciwave</entry> <entry>mdi</entry> </row>
|
||||
<row> <entry>menu</entry> <entry>menubuilder</entry> <entry>message</entry> <entry>metafile</entry> <entry>midi</entry> </row>
|
||||
<row> <entry>mmaux</entry> <entry>mmio</entry> <entry>mmsys</entry> <entry>mmtime</entry> <entry>module</entry> </row>
|
||||
<row> <entry>monthcal</entry> <entry>mpeg3</entry> <entry>mpr</entry> <entry>msacm</entry> <entry>msdmo</entry> </row>
|
||||
<row> <entry>msg</entry> <entry>mshtml</entry> <entry>msi</entry> <entry>msimg32</entry> <entry>msisys</entry> </row>
|
||||
<row> <entry>msrle32</entry> <entry>msvcrt</entry> <entry>msvideo</entry> <entry>mswsock</entry> <entry>nativefont</entry> </row>
|
||||
<row> <entry>netapi32</entry> <entry>netbios</entry> <entry>nls</entry> <entry>nonclient</entry> <entry>ntdll</entry> </row>
|
||||
<row> <entry>odbc</entry> <entry>ole</entry> <entry>oledlg</entry> <entry>olerelay</entry> <entry>opengl</entry> </row>
|
||||
<row> <entry>pager</entry> <entry>palette</entry> <entry>pidl</entry> <entry>powermgnt</entry> <entry>print</entry> </row>
|
||||
<row> <entry>process</entry> <entry>profile</entry> <entry>progress</entry> <entry>propsheet</entry> <entry>psapi</entry> </row>
|
||||
<row> <entry>psdrv</entry> <entry>qcap</entry> <entry>quartz</entry> <entry>ras</entry> <entry>rebar</entry> </row>
|
||||
<row> <entry>reg</entry> <entry>region</entry> <entry>relay</entry> <entry>resource</entry> <entry>richedit</entry> </row>
|
||||
<row> <entry>rundll32</entry> <entry>sblaster</entry> <entry>scroll</entry> <entry>seh</entry> <entry>selector</entry> </row>
|
||||
<row> <entry>server</entry> <entry>setupapi</entry> <entry>shdocvw</entry> <entry>shell</entry> <entry>shlctrl</entry> </row>
|
||||
<row> <entry>snmpapi</entry> <entry>snoop</entry> <entry>sound</entry> <entry>static</entry> <entry>statusbar</entry> </row>
|
||||
<row> <entry>storage</entry> <entry>stress</entry> <entry>string</entry> <entry>syscolor</entry> <entry>system</entry> </row>
|
||||
<row> <entry>tab</entry> <entry>tape</entry> <entry>tapi</entry> <entry>task</entry> <entry>text</entry> </row>
|
||||
<row> <entry>thread</entry> <entry>thunk</entry> <entry>tid</entry> <entry>timer</entry> <entry>toolbar</entry> </row>
|
||||
<row> <entry>toolhelp</entry> <entry>tooltips</entry> <entry>trackbar</entry> <entry>treeview</entry> <entry>ttydrv</entry> </row>
|
||||
<row> <entry>twain</entry> <entry>typelib</entry> <entry>uninstaller</entry> <entry>updown</entry> <entry>urlmon</entry> </row>
|
||||
<row> <entry>uxtheme</entry> <entry>ver</entry> <entry>virtual</entry> <entry>vxd</entry> <entry>wave</entry> </row>
|
||||
<row> <entry>wc_font</entry> <entry>win</entry> <entry>win32</entry> <entry>wineboot</entry> <entry>winecfg</entry> </row>
|
||||
<row> <entry>wineconsole</entry> <entry>wine_d3d</entry> <entry>winevdm</entry> <entry>wing</entry> <entry>winhelp</entry> </row>
|
||||
<row> <entry>wininet</entry> <entry>winmm</entry> <entry>winsock</entry> <entry>winspool</entry> <entry>wintab</entry> </row>
|
||||
<row> <entry>wintab32</entry> <entry>wnet</entry> <entry>x11drv</entry> <entry>x11settings</entry> <entry>xdnd</entry> </row>
|
||||
<row> <entry>xrandr</entry> <entry>xrender</entry> <entry>xvidmode</entry> </row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
<para>
|
||||
For more details about debug channels, check out the
|
||||
<ulink url="http://wine.codeweavers.com/docs/wine-devel/">
|
||||
The Wine Developer's Guide</ulink>.
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="wineserver-command-line-options">
|
||||
<title>wineserver Command Line Options</title>
|
||||
|
||||
<para>
|
||||
wineserver usually gets started automatically by Wine whenever
|
||||
the first wine process gets started.
|
||||
However, wineserver has some useful command line options that
|
||||
you can add if you start it up manually, e.g. via a user login
|
||||
script or so.
|
||||
</para>
|
||||
|
||||
<sect2 id="wineserver-config-parameter">
|
||||
<title>-d<n></title>
|
||||
<para>
|
||||
Sets the debug level for debug output in the terminal that
|
||||
wineserver got started in at level <n>.
|
||||
In other words: everything greater than 0 will enable
|
||||
wineserver specific debugging output.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>-h</title>
|
||||
<para>
|
||||
Display wineserver command line options help message.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>-k[n]</title>
|
||||
<para>
|
||||
Kill the current wineserver, optionally with signal n.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>-p[n]</title>
|
||||
<para>
|
||||
This parameter makes wineserver persistent, optionally for n
|
||||
seconds. It will prevent wineserver from shutting down immediately.
|
||||
</para>
|
||||
<para>
|
||||
Usually, wineserver quits almost immediately after the last
|
||||
wine process using this wineserver terminated.
|
||||
However, since wineserver loads a lot of things on startup
|
||||
(such as the whole Windows registry data), its startup might
|
||||
be so slow that it's very useful to keep it from exiting after
|
||||
the end of all Wine sessions, by making it persistent.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>-w</title>
|
||||
<para>
|
||||
This parameter makes a newly started wineserver wait until the
|
||||
currently active wineserver instance terminates.
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="environment-variables">
|
||||
<title>Setting Windows/DOS environment variables</title>
|
||||
<para>
|
||||
Your program might require some environment variable to be set
|
||||
properly in order to run successfully.
|
||||
In this case you need to set this environment variable in the
|
||||
Linux shell, since Wine will pass on the entire shell environment
|
||||
variable settings to the Windows environment variable space.
|
||||
Example for the bash shell (other shells may have a different syntax
|
||||
!):
|
||||
<screen>
|
||||
export MYENVIRONMENTVAR=myenvironmentvarsetting
|
||||
</screen>
|
||||
This will make sure your Windows program can access the
|
||||
MYENVIRONMENTVAR environment variable once you start your program
|
||||
using Wine.
|
||||
If you want to have MYENVIRONMENTVAR set permanently, then you can
|
||||
place the setting into /etc/profile, or also ~/.bashrc in the case of
|
||||
bash.
|
||||
</para>
|
||||
<para>Note however that there are some exceptions to the rule:
|
||||
If you want to change the PATH, SYSTEM or TEMP variables, the of course
|
||||
you can't modify it that way, since this will alter the Unix environment
|
||||
settings. Instead, you should set them into the registry. To set them
|
||||
you should launch <userinput>wine regedit</userinput> and then go to the
|
||||
<screen>HKEY_CURRENT_USER/Environment</screen> key. Now you can create
|
||||
or modify the values of the variables you need
|
||||
</para>
|
||||
<para>
|
||||
<programlisting>"System" = "c:\\windows\\system"</programlisting>
|
||||
This sets up where the windows system files are. The Windows
|
||||
system directory should reside below the directory used for the
|
||||
<literal>Windows</literal> setting.
|
||||
Thus when using /usr/local/wine_c_windows as Windows path,
|
||||
the system directory would be
|
||||
<filename>/usr/local/wine_c/windows/system</filename>.
|
||||
It must be set with no trailing slash, and you must be sure that
|
||||
you have write access to it.
|
||||
</para>
|
||||
<para>
|
||||
<programlisting>"Temp" = "c:\\temp"</programlisting> This should
|
||||
be the directory you want your temp files stored in,
|
||||
/usr/local/wine_c/temp in our previous example.
|
||||
Again, no trailing slash, and <emphasis>write
|
||||
access</emphasis>!!
|
||||
</para>
|
||||
<para>
|
||||
<programlisting>"Path" = "c:\\windows;c:\\windows\\system;c:\\blanco"</programlisting>
|
||||
Behaves like the <envar>PATH</envar> setting on UNIX
|
||||
boxes. When wine is run like <userinput>wine
|
||||
sol.exe</userinput>, if <filename>sol.exe</filename>
|
||||
resides in a directory specified in the
|
||||
<literal>Path</literal> setting, wine will run it (Of
|
||||
course, if <filename>sol.exe</filename> resides in the
|
||||
current directory, wine will run that one). Make sure it
|
||||
always has your <filename>windows</filename> directory and
|
||||
system directory (For this setup, it must have
|
||||
<filename>"c:\\windows;c:\\windows\\system"</filename>).
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="CUI-programs">
|
||||
<title>Text mode programs (CUI: Console User Interface)</title>
|
||||
<para>Text mode programs are program which output is only made
|
||||
out of text (surprise!). In Windows terminology, they are
|
||||
called CUI (Console User Interface) executables, by opposition
|
||||
to GUI (Graphical User Interface) executables. Win32 API
|
||||
provide a complete set of APIs to handle this situation, which
|
||||
goes from basic features like text printing, up to high level
|
||||
functionalities (like full screen editing, color support,
|
||||
cursor motion, mouse support), going through features like
|
||||
line editing or raw/cooked input stream support
|
||||
</para>
|
||||
<para>
|
||||
Given the wide scope of features above, and the current usage
|
||||
in Un*x world, Wine comes out with three different ways for
|
||||
running a console program (aka a CUI executable):
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
bare streams
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
wineconsole with user backend
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
wineconsole with curses backend
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
<para>The names here are a bit obscure. "bare streams" means
|
||||
that no extra support of wine is provide to map between the
|
||||
unix console access and Windows console access. The two other
|
||||
ways require the use of a specific Wine program (wineconsole)
|
||||
which provide extended facilities. The following table
|
||||
describes what you can do (and cannot do) with those three
|
||||
ways.
|
||||
<table>
|
||||
<title>Basic differences in consoles</title>
|
||||
<tgroup cols="4" align="left">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Function</entry>
|
||||
<entry>Bare streams</entry>
|
||||
<entry>Wineconsole & user backend</entry>
|
||||
<entry>Wineconsole & curses backend</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>How to run (assuming executable is called foo.exe)</entry>
|
||||
<entry><msgtext>
|
||||
<screen><prompt>$</prompt> <userinput>wine foo.exe</userinput></screen>
|
||||
</msgtext></entry>
|
||||
<entry><msgtext>
|
||||
<screen><prompt>$</prompt> <userinput>wineconsole -- --backend=user foo.exe</userinput></screen>
|
||||
</msgtext></entry>
|
||||
<entry><msgtext>
|
||||
<screen><prompt>$</prompt> <userinput>wineconsole foo.exe</userinput></screen>
|
||||
</msgtext>You can also use --backend=curses as an option</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>Good support for line oriented CUI applications
|
||||
(which print information line after line)
|
||||
</entry>
|
||||
<entry>Yes</entry>
|
||||
<entry>Yes</entry>
|
||||
<entry>Yes</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>Good support for full screen CUI
|
||||
applications (including but not limited to color
|
||||
support, mouse support...)</entry>
|
||||
<entry>No</entry>
|
||||
<entry>Yes</entry>
|
||||
<entry>Yes</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>Can be run even if X11 is not running</entry>
|
||||
<entry>Yes</entry>
|
||||
<entry>No</entry>
|
||||
<entry>Yes</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>Implementation</entry>
|
||||
<entry>Maps the standard Windows streams to the
|
||||
standard Unix streams (stdin/stdout/stderr)
|
||||
</entry>
|
||||
<entry>
|
||||
Wineconsole will create a new Window (hence
|
||||
requiring the USER32 DLL is available) where all
|
||||
information will be displayed
|
||||
</entry>
|
||||
<entry>
|
||||
Wineconsole will use existing unix console
|
||||
(from which the program is run) and with the help of
|
||||
the (n)curses library take control of all the terminal
|
||||
surface for interacting with the user
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>Known limitations</entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry>
|
||||
Will produce strange behavior if two (or more)
|
||||
Windows consoles are used on the same Un*x terminal.
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</para>
|
||||
<sect2 id="CUI-programs-config">
|
||||
<title>Configuration of CUI executables</title>
|
||||
<para>
|
||||
When wineconsole is used, several configuration options are
|
||||
available. Wine (as Windows do) stores, on a per application
|
||||
basis, several options in the registry. This let a user, for
|
||||
example, define the default screen-buffer size he would like
|
||||
to have for a given application.
|
||||
</para>
|
||||
<para>
|
||||
As of today, only the USER backend allows you to edit those
|
||||
options (we don't recommend editing by hand the registry
|
||||
contents). This edition is fired when a user right click in
|
||||
the console (this popups a menu), where you can either
|
||||
choose from:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
Default: this will edit the settings shared by all
|
||||
applications which haven't been configured yet. So,
|
||||
when an application is first run (on your machine,
|
||||
under your account) in wineconsole, wineconsole will
|
||||
inherit this default settings for the
|
||||
application. Afterwards, the application will have its
|
||||
own settings, that you'll be able to modify at your will.
|
||||
</para>
|
||||
<para>
|
||||
Properties: this will edit the application's
|
||||
settings. When you're done, with the edition, you'll
|
||||
be prompted whether you want to:
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
Keep these modified settings only for this
|
||||
session (next time you run the application, you
|
||||
will not see the modification you've just made).
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Use the settings for this session and save them
|
||||
as well, so that next you run your application,
|
||||
you'll use these new settings again.
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
<para>
|
||||
Here's the list of the items you can configure, and their
|
||||
meanings:
|
||||
<table>
|
||||
<title>Wineconsole configuration options</title>
|
||||
<tgroup cols="2" align="left">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Configuration option</entry>
|
||||
<entry>Meaning</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>Cursor's size</entry>
|
||||
<entry>
|
||||
Defines the size of the cursor. Three options are
|
||||
available: small (33% of character height), medium
|
||||
(66%) and large (100%)
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>Popup menu</entry>
|
||||
<entry>
|
||||
It's been said earlier that wineconsole
|
||||
configuration popup was triggered using a right
|
||||
click in the console's window. However, this can
|
||||
be an issue when the application you run inside
|
||||
wineconsole expects the right click events to be
|
||||
sent to it. By ticking control or shift you select
|
||||
additional modifiers on the right click for
|
||||
opening the popup. For example, ticking shift will
|
||||
send events to the application when you right
|
||||
click the window without shift being hold down,
|
||||
and open the window when you right-click while
|
||||
shift being hold down.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>Quick edit</entry>
|
||||
<entry>
|
||||
This tick box lets you decide whether left-click
|
||||
mouse events shall be interpreted as events to be
|
||||
sent to the underlying application (tick off) or
|
||||
as a selection of rectangular part of the screen
|
||||
to be later on copied onto the clipboard (tick on).
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>History</entry>
|
||||
<entry>
|
||||
This lets you pick up how many commands you want
|
||||
the console to recall. You can also drive whether
|
||||
you want, when entering several times the same
|
||||
command - potentially intertwined with others -
|
||||
whether you want to store all of them (tick off)
|
||||
or only the last one (tick on).
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>Police</entry>
|
||||
<entry>
|
||||
The Police property sheet allows you to pick the
|
||||
default font for the console (font file, size,
|
||||
background and foreground color).
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>Screenbuffer & window size</entry>
|
||||
<entry>
|
||||
The console as you see it is made of two different
|
||||
parts. On one hand there's the screenbuffer which
|
||||
contains all the information your application puts
|
||||
on the screen, and the window which displays a
|
||||
given area of this screen buffer. Note that the
|
||||
window is always smaller or of the same size than
|
||||
the screen buffer. Having a strictly smaller window
|
||||
size will put on scrollbars on the window so that
|
||||
you can see the whole screenbuffer's content.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>Close on exit</entry>
|
||||
<entry>
|
||||
If it's ticked, then the wineconsole will exit
|
||||
when the application within terminates. Otherwise,
|
||||
it'll remain opened until the user manually closes
|
||||
it: this allows seeing the latest information of a
|
||||
program after it has terminated.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>Edition mode</entry>
|
||||
<entry>
|
||||
<msgtext>
|
||||
<para>
|
||||
When the user enter commands, he or she can
|
||||
choose between several edition modes:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
Emacs: the same keybindings as under
|
||||
emacs are available. For example, Ctrl-A
|
||||
will bring the cursor to the beginning
|
||||
of the edition line. See your emacs
|
||||
manual for the details of the commands.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Win32: these are the standard Windows
|
||||
console key-bindings (mainly using
|
||||
arrows).
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</msgtext>
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
||||
<!-- Keep this comment at the end of the file
|
||||
Local variables:
|
||||
mode: sgml
|
||||
sgml-parent-document:("wine-user.sgml" "set" "book" "chapter" "")
|
||||
End:
|
||||
-->
|
|
@ -1,591 +0,0 @@
|
|||
<chapter id="testing">
|
||||
<title>Writing Conformance tests</title>
|
||||
|
||||
<sect1 id="testing-intro">
|
||||
<title>Introduction</title>
|
||||
<para>
|
||||
The Windows API follows no standard, it is itself a de facto standard,
|
||||
and deviations from that standard, even small ones, often cause
|
||||
applications to crash or misbehave in some way.
|
||||
</para>
|
||||
<para>
|
||||
The question becomes, "How do we ensure compliance with that standard?"
|
||||
The answer is, "By using the API documentation available to us and
|
||||
backing that up with conformance tests." Furthermore, a conformance
|
||||
test suite is the most accurate (if not necessarily the most complete)
|
||||
form of API documentation and can be used to supplement the Windows
|
||||
API documentation.
|
||||
</para>
|
||||
<para>
|
||||
Writing a conformance test suite for more than 10000 APIs is no small
|
||||
undertaking. Fortunately it can prove very useful to the development
|
||||
of Wine way before it is complete.
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
The conformance test suite must run on Windows. This is
|
||||
necessary to provide a reasonable way to verify its accuracy.
|
||||
Furthermore the tests must pass successfully on all Windows
|
||||
platforms (tests not relevant to a given platform should be
|
||||
skipped).
|
||||
</para>
|
||||
<para>
|
||||
A consequence of this is that the test suite will provide a
|
||||
great way to detect variations in the API between different
|
||||
Windows versions. For instance, this can provide insights
|
||||
into the differences between the, often undocumented, Win9x and
|
||||
NT Windows families.
|
||||
</para>
|
||||
<para>
|
||||
However, one must remember that the goal of Wine is to run
|
||||
Windows applications on Linux, not to be a clone of any specific
|
||||
Windows version. So such variations must only be tested for when
|
||||
relevant to that goal.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Writing conformance tests is also an easy way to discover
|
||||
bugs in Wine. Of course, before fixing the bugs discovered in
|
||||
this way, one must first make sure that the new tests do pass
|
||||
successfully on at least one Windows 9x and one Windows NT
|
||||
version.
|
||||
</para>
|
||||
<para>
|
||||
Bugs discovered this way should also be easier to fix. Unlike
|
||||
some mysterious application crashes, when a conformance test
|
||||
fails, the expected behavior and APIs tested for are known thus
|
||||
greatly simplifying the diagnosis.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
To detect regressions. Simply running the test suite regularly
|
||||
in Wine turns it into a great tool to detect regressions.
|
||||
When a test fails, one immediately knows what was the expected
|
||||
behavior and which APIs are involved. Thus regressions caught
|
||||
this way should be detected earlier, because it is easy to run
|
||||
all tests on a regular basis, and be easier to fix because of the
|
||||
reduced diagnosis work.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Tests written in advance of the Wine development (possibly even
|
||||
by non Wine developers) can also simplify the work of the
|
||||
future implementer by making it easier for him to check the
|
||||
correctness of his code.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Conformance tests will also come in handy when testing Wine on
|
||||
new (or not as widely used) architectures such as FreeBSD,
|
||||
Solaris x86 or even non-x86 systems. Even when the port does
|
||||
not involve any significant change in the thread management,
|
||||
exception handling or other low-level aspects of Wine, new
|
||||
architectures can expose subtle bugs that can be hard to
|
||||
diagnose when debugging regular (complex) applications.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
|
||||
<sect1 id="testing-what">
|
||||
<title>What to test for?</title>
|
||||
<para>
|
||||
The first thing to test for is the documented behavior of APIs
|
||||
and such as CreateFile. For instance one can create a file using a
|
||||
long pathname, check that the behavior is correct when the file
|
||||
already exists, try to open the file using the corresponding short
|
||||
pathname, convert the filename to Unicode and try to open it using
|
||||
CreateFileW, and all other things which are documented and that
|
||||
applications rely on.
|
||||
</para>
|
||||
<para>
|
||||
While the testing framework is not specifically geared towards this
|
||||
type of tests, it is also possible to test the behavior of Windows
|
||||
messages. To do so, create a window, preferably a hidden one so that
|
||||
it does not steal the focus when running the tests, and send messages
|
||||
to that window or to controls in that window. Then, in the message
|
||||
procedure, check that you receive the expected messages and with the
|
||||
correct parameters.
|
||||
</para>
|
||||
<para>
|
||||
For instance you could create an edit control and use WM_SETTEXT to
|
||||
set its contents, possibly check length restrictions, and verify the
|
||||
results using WM_GETTEXT. Similarly one could create a listbox and
|
||||
check the effect of LB_DELETESTRING on the list's number of items,
|
||||
selected items list, highlighted item, etc. For concrete examples,
|
||||
see <filename>dlls/user/tests/win.c</> and the related tests.
|
||||
</para>
|
||||
<para>
|
||||
However, undocumented behavior should not be tested for unless there
|
||||
is an application that relies on this behavior, and in that case the
|
||||
test should mention that application, or unless one can strongly
|
||||
expect applications to rely on this behavior, typically APIs that
|
||||
return the required buffer size when the buffer pointer is NULL.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
|
||||
<sect1 id="testing-wine">
|
||||
<title>Running the tests in Wine</title>
|
||||
<para>
|
||||
The simplest way to run the tests in Wine is to type 'make test' in
|
||||
the Wine sources top level directory. This will run all the Wine
|
||||
conformance tests.
|
||||
</para>
|
||||
<para>
|
||||
The tests for a specific Wine library are located in a 'tests'
|
||||
directory in that library's directory. Each test is contained in a
|
||||
file (e.g. <filename>dlls/kernel/tests/thread.c</>). Each
|
||||
file itself contains many checks concerning one or more related APIs.
|
||||
</para>
|
||||
<para>
|
||||
So to run all the tests related to a given Wine library, go to the
|
||||
corresponding 'tests' directory and type 'make test'. This will
|
||||
compile the tests, run them, and create an '<replaceable>xxx</>.ok'
|
||||
file for each test that passes successfully. And if you only want to
|
||||
run the tests contained in the <filename>thread.c</> file of the
|
||||
kernel library, you would do:
|
||||
<screen>
|
||||
<prompt>$ </>cd dlls/kernel/tests
|
||||
<prompt>$ </>make thread.ok
|
||||
</screen>
|
||||
</para>
|
||||
<para>
|
||||
Note that if the test has already been run and is up to date (i.e. if
|
||||
neither the kernel library nor the <filename>thread.c</> file has
|
||||
changed since the <filename>thread.ok</> file was created), then make
|
||||
will say so. To force the test to be re-run, delete the
|
||||
<filename>thread.ok</> file, and run the make command again.
|
||||
</para>
|
||||
<para>
|
||||
You can also run tests manually using a command similar to the
|
||||
following:
|
||||
<screen>
|
||||
<prompt>$ </>../../../tools/runtest -q -M kernel32.dll -p kernel32_test.exe.so thread.c
|
||||
<prompt>$ </>../../../tools/runtest -P wine -p kernel32_test.exe.so thread.c
|
||||
thread.c: 86 tests executed, 5 marked as todo, 0 failures.
|
||||
</screen>
|
||||
The '-P wine' option defines the platform that is currently being
|
||||
tested and is used in conjunction with the 'todo' statements (see
|
||||
below). Remove the '-q' option if you want the testing framework
|
||||
to report statistics about the number of successful and failed tests.
|
||||
Run <command>runtest -h</> for more details.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
|
||||
<sect1 id="cross-compiling-tests">
|
||||
<title>Cross-compiling the tests with MinGW</title>
|
||||
<sect2>
|
||||
<title>Setup of the MinGW cross-compiling environment</title>
|
||||
<para>
|
||||
Here are some instructions to setup MinGW on different Linux
|
||||
distributions and *BSD.
|
||||
</para>
|
||||
<sect3>
|
||||
<title>Debian GNU/Linux</title>
|
||||
<para>
|
||||
On Debian do <command>apt-get install mingw32</>.
|
||||
</para>
|
||||
<para>
|
||||
The standard MinGW libraries will probably be incomplete, causing
|
||||
'undefined symbol' errors. So get the latest
|
||||
<ulink url="http://mirzam.it.vu.nl/mingw/">mingw-w32api RPM</>
|
||||
and use <command>alien</> to either convert it to a .tar.gz file
|
||||
from which to extract just the relevant files, or to convert it
|
||||
to a Debian package that you will install.
|
||||
</para>
|
||||
</sect3>
|
||||
<sect3>
|
||||
<title>Red Hat Linux like rpm systems</title>
|
||||
<para>
|
||||
This includes Fedora Core, Red Hat Enterprise Linux, Mandrake,
|
||||
most probably SuSE Linux too, etc. But this list isn't exhaustive;
|
||||
the following steps should probably work on any rpm based system.
|
||||
</para>
|
||||
<para>
|
||||
Download and install the latest rpm's from
|
||||
<ulink url="http://mirzam.it.vu.nl/mingw/">MinGW RPM packages</>.
|
||||
Alternatively you can follow the instructions on that page and
|
||||
build your own packages from the source rpm's listed there as well.
|
||||
</para>
|
||||
</sect3>
|
||||
<sect3>
|
||||
<title>*BSD</title>
|
||||
<para>
|
||||
The *BSD systems have in their ports collection a port for the
|
||||
MinGW cross-compiling environment. Please see the documentation
|
||||
of your system about how to build and install a port.
|
||||
</para>
|
||||
</sect3>
|
||||
</sect2>
|
||||
<sect2>
|
||||
<title>Compiling the tests</title>
|
||||
<para>
|
||||
Having the cross-compiling environment set up the generation of the
|
||||
Windows executables is easy by using the Wine build system.
|
||||
</para>
|
||||
<para>
|
||||
If you had already run <command>configure</>, then delete
|
||||
<filename>config.cache</> and re-run <command>configure</>.
|
||||
You can then run <command>make crosstest</>. To sum up:
|
||||
<screen>
|
||||
<prompt>$ </><userinput>rm config.cache</>
|
||||
<prompt>$ </><userinput>./configure</>
|
||||
<prompt>$ </><userinput>make crosstest</>
|
||||
</screen>
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
|
||||
<sect1 id="testing-windows">
|
||||
<title>Building and running the tests on Windows</title>
|
||||
<sect2>
|
||||
<title>Using pre-compiled binaries</title>
|
||||
<para>
|
||||
The simplest solution is to download the
|
||||
<ulink url="http://www.astro.gla.ac.uk/users/paulm/WRT/CrossBuilt/winetest-latest.exe">latest
|
||||
version of winetest</>. This executable contains all the Wine
|
||||
conformance tests, runs them and reports the results.
|
||||
</para>
|
||||
<para>
|
||||
You can also get the older versions from
|
||||
<ulink url="http://www.astro.gla.ac.uk/users/paulm/WRT/CrossBuilt/">Paul
|
||||
Millar's website</>.
|
||||
</para>
|
||||
</sect2>
|
||||
<sect2>
|
||||
<title>With Visual C++</title>
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
If you are using Visual Studio 6, make sure you have the
|
||||
"processor pack" from
|
||||
<ulink url="http://msdn.microsoft.com/vstudio/downloads/tools/ppack/default.aspx">http://msdn.microsoft.com/vstudio/downloads/tools/ppack/default.aspx</>.
|
||||
The processor pack fixes <emphasis>"error C2520: conversion from
|
||||
unsigned __int64 to double not implemented, use signed __int64"</>.
|
||||
However note that the "processor pack" is incompatible with
|
||||
Visual Studio 6.0 Standard Edition, and with the Visual Studio 6
|
||||
Service Pack 6. If you are using Visual Studio 7 or greater you
|
||||
do not need the processor pack. In either case it is recommended
|
||||
to the most recent compatible Visual Studio
|
||||
<ulink url="http://msdn.microsoft.com/vstudio/downloads/updates/sp/">service pack</>.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
get the Wine sources
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
Run msvcmaker to generate Visual C++ project files for the tests.
|
||||
'msvcmaker' is a perl script so you may be able to run it on
|
||||
Windows.
|
||||
<screen>
|
||||
<prompt>$ </>./tools/winapi/msvcmaker --no-wine
|
||||
</screen>
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
If the previous steps were done on your Linux development
|
||||
machine, make the Wine sources accessible to the Windows machine
|
||||
on which you are going to compile them. Typically you would do
|
||||
this using Samba but copying them altogether would work too.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
On the Windows machine, open the <filename>winetest.dsw</>
|
||||
workspace. This will load each test's project. For each test there
|
||||
are two configurations: one compiles the test with the Wine
|
||||
headers, and the other uses the Microsoft headers.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
If you choose the "Win32 MSVC Headers" configuration, most of the
|
||||
tests will not compile with the regular Visual Studio headers. So
|
||||
to use this configuration, download and install a recent
|
||||
<ulink url="http://www.microsoft.com/msdownload/platformsdk/sdkupdate/">Platform SDK</>
|
||||
as well as the latest <ulink url="http://msdn.microsoft.com/library/default.asp?url=/downloads/list/directx.asp">DirectX SDK</>.
|
||||
Then, <ulink url="http://msdn.microsoft.com/library/default.asp?url=/library/EN-US/sdkintro/sdkintro/installing_the_platform_sdk_with_visual_studio.asp">configure Visual Studio</>
|
||||
to use these SDK's headers and libraries. Alternately you could go
|
||||
to the <menuchoice><guimenu>Project</> <guimenu>Settings...</></>
|
||||
menu and modify the settings appropriately, but you would then
|
||||
have to redo this whenever you rerun msvcmaker.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
Open the <menuchoice><guimenu>Build</> <guimenu>Batch
|
||||
build...</></> menu and select the tests and build configurations
|
||||
you want to build. Then click on <guibutton>Build</>.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
To run a specific test from Visual C++, go to
|
||||
<menuchoice><guimenu>Project</> <guimenu>Settings...</></>. There
|
||||
select that test's project and build configuration and go to the
|
||||
<guilabel>Debug</> tab. There type the name of the specific test
|
||||
to run (e.g. 'thread') in the <guilabel>Program arguments</>
|
||||
field. Validate your change by clicking on <guibutton>Ok</> and
|
||||
start the test by clicking the red exclamation mark (or hitting
|
||||
'F5' or any other usual method).
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
You can also run the tests from the command line. You will find
|
||||
them in either <filename>Output\Win32_Wine_Headers</> or
|
||||
<filename>Output\Win32_MSVC_Headers</> depending on the build
|
||||
method. So to run the kernel 'path' tests you would do:
|
||||
<screen>
|
||||
<prompt>C:\></>cd dlls\kernel\tests\Output\Win32_MSVC_Headers
|
||||
<prompt>C:\wine\dlls\kernel\tests\Output\Win32_MSVC_Headers></> kernel32_test path
|
||||
</screen>
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
</sect2>
|
||||
<sect2>
|
||||
<title>With MinGW</title>
|
||||
<para>
|
||||
Wine's build system already has support for building tests with a MinGW
|
||||
cross-compiler. See the section above called 'Setup of the MinGW
|
||||
cross-compiling environment' for instructions on how to set things up.
|
||||
When you have a MinGW environment installed all you need to do is rerun
|
||||
configure and it should detect the MinGW compiler and tools. Then run
|
||||
'make crosstest' to start building the tests.
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
|
||||
<sect1 id="testing-test">
|
||||
<title>Inside a test</title>
|
||||
|
||||
<para>
|
||||
When writing new checks you can either modify an existing test file or
|
||||
add a new one. If your tests are related to the tests performed by an
|
||||
existing file, then add them to that file. Otherwise create a new .c
|
||||
file in the tests directory and add that file to the
|
||||
<varname>CTESTS</> variable in <filename>Makefile.in</>.
|
||||
</para>
|
||||
<para>
|
||||
A new test file will look something like the following:
|
||||
<screen>
|
||||
#include <wine/test.h>
|
||||
#include <winbase.h>
|
||||
|
||||
/* Maybe auxiliary functions and definitions here */
|
||||
|
||||
START_TEST(paths)
|
||||
{
|
||||
/* Write your checks there or put them in functions you will call from
|
||||
* there
|
||||
*/
|
||||
}
|
||||
</screen>
|
||||
</para>
|
||||
<para>
|
||||
The test's entry point is the START_TEST section. This is where
|
||||
execution will start. You can put all your tests in that section but
|
||||
it may be better to split related checks in functions you will call
|
||||
from the START_TEST section. The parameter to START_TEST must match
|
||||
the name of the C file. So in the above example the C file would be
|
||||
called <filename>paths.c</>.
|
||||
</para>
|
||||
<para>
|
||||
Tests should start by including the <filename>wine/test.h</> header.
|
||||
This header will provide you access to all the testing framework
|
||||
functions. You can then include the windows header you need, but make
|
||||
sure to not include any Unix or Wine specific header: tests must
|
||||
compile on Windows.
|
||||
</para>
|
||||
<para>
|
||||
You can use <function>trace</> to print informational messages. Note
|
||||
that these messages will only be printed if 'runtest -v' is being used.
|
||||
<screen>
|
||||
trace("testing GlobalAddAtomA\n");
|
||||
trace("foo=%d\n",foo);
|
||||
</screen>
|
||||
</para>
|
||||
<para>
|
||||
Then just call functions and use <function>ok</> to make sure that
|
||||
they behaved as expected:
|
||||
<screen>
|
||||
ATOM atom = GlobalAddAtomA( "foobar" );
|
||||
ok( GlobalFindAtomA( "foobar" ) == atom, "could not find atom foobar\n" );
|
||||
ok( GlobalFindAtomA( "FOOBAR" ) == atom, "could not find atom FOOBAR\n" );
|
||||
</screen>
|
||||
The first parameter of <function>ok</> is an expression which must
|
||||
evaluate to true if the test was successful. The next parameter is a
|
||||
printf-compatible format string which is displayed in case the test
|
||||
failed, and the following optional parameters depend on the format
|
||||
string.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="testing-error-messages">
|
||||
<title>Writing good error messages</title>
|
||||
<para>
|
||||
The message that is printed when a test fails is
|
||||
<emphasis>extremely</> important.
|
||||
</para>
|
||||
<para>
|
||||
Someone will take your test, run it on a Windows platform that
|
||||
you don't have access to, and discover that it fails. They will then
|
||||
post an email with the output of the test, and in particular your
|
||||
error message. Someone, maybe you, will then have to figure out from
|
||||
this error message why the test failed.
|
||||
</para>
|
||||
<para>
|
||||
If the error message contains all the relevant information that will
|
||||
be easy. If not, then it will require modifying the test, finding
|
||||
someone to compile it on Windows, sending the modified version to the
|
||||
original tester and waiting for his reply. In other words, it will
|
||||
be long and painful.
|
||||
</para>
|
||||
<para>
|
||||
So how do you write a good error message? Let's start with an example
|
||||
of a bad error message:
|
||||
<screen>
|
||||
ok(GetThreadPriorityBoost(curthread,&disabled)!=0,
|
||||
"GetThreadPriorityBoost Failed\n");
|
||||
</screen>
|
||||
This will yield:
|
||||
<screen>
|
||||
thread.c:123: Test failed: GetThreadPriorityBoost Failed
|
||||
</screen>
|
||||
</para>
|
||||
<para>
|
||||
Did you notice how the error message provides no information about
|
||||
why the test failed? We already know from the line number exactly
|
||||
which test failed. In fact the error message gives strictly no
|
||||
information that cannot already be obtained by reading the code. In
|
||||
other words it provides no more information than an empty string!
|
||||
</para>
|
||||
<para>
|
||||
Let's look at how to rewrite it:
|
||||
<screen>
|
||||
BOOL rc;
|
||||
...
|
||||
rc=GetThreadPriorityBoost(curthread,&disabled);
|
||||
ok(rc!=0 && disabled==0,"rc=%d error=%ld disabled=%d\n",
|
||||
rc,GetLastError(),disabled);
|
||||
</screen>
|
||||
This will yield:
|
||||
<screen>
|
||||
thread.c:123: Test failed: rc=0 error=120 disabled=0
|
||||
</screen>
|
||||
</para>
|
||||
<para>
|
||||
When receiving such a message, one would check the source, see that
|
||||
it's a call to GetThreadPriorityBoost, that the test failed not
|
||||
because the API returned the wrong value, but because it returned an
|
||||
error code. Furthermore we see that GetLastError() returned 120 which
|
||||
winerror.h defines as ERROR_CALL_NOT_IMPLEMENTED. So the source of
|
||||
the problem is obvious: this Windows platform (here Windows 98) does
|
||||
not support this API and thus the test must be modified to detect
|
||||
such a condition and skip the test.
|
||||
</para>
|
||||
<para>
|
||||
So a good error message should provide all the information which
|
||||
cannot be obtained by reading the source, typically the function
|
||||
return value, error codes, and any function output parameter. Even if
|
||||
more information is needed to fully understand a problem,
|
||||
systematically providing the above is easy and will help cut down the
|
||||
number of iterations required to get to a resolution.
|
||||
</para>
|
||||
<para>
|
||||
It may also be a good idea to dump items that may be hard to retrieve
|
||||
from the source, like the expected value in a test if it is the
|
||||
result of an earlier computation, or comes from a large array of test
|
||||
values (e.g. index 112 of _pTestStrA in vartest.c). In that respect,
|
||||
for some tests you may want to define a macro such as the following:
|
||||
<screen>
|
||||
#define eq(received, expected, label, type) \
|
||||
ok((received) == (expected), "%s: got " type " instead of " type "\n", (label),(received),(expected))
|
||||
|
||||
...
|
||||
|
||||
eq( b, curr_val, "SPI_{GET,SET}BEEP", "%d" );
|
||||
</screen>
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
|
||||
<sect1 id="testing-platforms">
|
||||
<title>Handling platform issues</title>
|
||||
<para>
|
||||
Some checks may be written before they pass successfully in Wine.
|
||||
Without some mechanism, such checks would potentially generate
|
||||
hundred of known failures for months each time the tests are being run.
|
||||
This would make it hard to detect new failures caused by a regression.
|
||||
or to detect that a patch fixed a long standing issue.
|
||||
</para>
|
||||
<para>
|
||||
Thus the Wine testing framework has the concept of platforms and
|
||||
groups of checks can be declared as expected to fail on some of them.
|
||||
In the most common case, one would declare a group of tests as
|
||||
expected to fail in Wine. To do so, use the following construct:
|
||||
<screen>
|
||||
todo_wine {
|
||||
SetLastError( 0xdeadbeef );
|
||||
ok( GlobalAddAtomA(0) == 0 && GetLastError() == 0xdeadbeef, "failed to add atom 0\n" );
|
||||
}
|
||||
</screen>
|
||||
On Windows the above check would be performed normally, but on Wine it
|
||||
would be expected to fail, and not cause the failure of the whole
|
||||
test. However. If that check were to succeed in Wine, it would
|
||||
cause the test to fail, thus making it easy to detect when something
|
||||
has changed that fixes a bug. Also note that todo checks are accounted
|
||||
separately from regular checks so that the testing statistics remain
|
||||
meaningful. Finally, note that todo sections can be nested so that if
|
||||
a test only fails on the cygwin and reactos platforms, one would
|
||||
write:
|
||||
<screen>
|
||||
todo("cygwin") {
|
||||
todo("reactos") {
|
||||
...
|
||||
}
|
||||
}
|
||||
</screen>
|
||||
<!-- FIXME: Would we really have platforms such as reactos, cygwin, freebsd & co? -->
|
||||
But specific platforms should not be nested inside a todo_wine section
|
||||
since that would be redundant.
|
||||
</para>
|
||||
<para>
|
||||
When writing tests you will also encounter differences between Windows
|
||||
9x and Windows NT platforms. Such differences should be treated
|
||||
differently from the platform issues mentioned above. In particular
|
||||
you should remember that the goal of Wine is not to be a clone of any
|
||||
specific Windows version but to run Windows applications on Unix.
|
||||
</para>
|
||||
<para>
|
||||
So, if an API returns a different error code on Windows 9x and
|
||||
Windows NT, your check should just verify that Wine returns one or
|
||||
the other:
|
||||
<screen>
|
||||
ok ( GetLastError() == WIN9X_ERROR || GetLastError() == NT_ERROR, ...);
|
||||
</screen>
|
||||
</para>
|
||||
<para>
|
||||
If an API is only present on some Windows platforms, then use
|
||||
LoadLibrary and GetProcAddress to check if it is implemented and
|
||||
invoke it. Remember, tests must run on all Windows platforms.
|
||||
Similarly, conformance tests should nor try to correlate the Windows
|
||||
version returned by GetVersion with whether given APIs are
|
||||
implemented or not. Again, the goal of Wine is to run Windows
|
||||
applications (which do not do such checks), and not be a clone of a
|
||||
specific Windows version.
|
||||
</para>
|
||||
<!--para>
|
||||
FIXME: What about checks that cause the process to crash due to a bug?
|
||||
</para-->
|
||||
</sect1>
|
||||
|
||||
|
||||
<!-- FIXME: Strategies for testing threads, testing network stuff,
|
||||
file handling... -->
|
||||
|
||||
</chapter>
|
||||
|
||||
<!-- Keep this comment at the end of the file
|
||||
Local variables:
|
||||
mode: sgml
|
||||
sgml-parent-document:("wine-devel.sgml" "set" "book" "part" "chapter" "")
|
||||
End:
|
||||
-->
|
|
@ -1,133 +0,0 @@
|
|||
<!doctype book PUBLIC "-//OASIS//DTD DocBook V3.1//EN" [
|
||||
|
||||
<!entity debugger SYSTEM "debugger.sgml">
|
||||
<!entity debugging SYSTEM "debugging.sgml">
|
||||
<!entity otherdebug SYSTEM "winedev-otherdebug.sgml">
|
||||
<!entity codingpractice SYSTEM "winedev-coding.sgml">
|
||||
<!entity testing SYSTEM "testing.sgml">
|
||||
<!entity documentation SYSTEM "documentation.sgml">
|
||||
|
||||
<!entity architecture SYSTEM "architecture.sgml">
|
||||
<!entity kernel SYSTEM "winedev-kernel.sgml">
|
||||
<!entity graphical SYSTEM "winedev-graphical.sgml">
|
||||
<!entity windowing SYSTEM "winedev-windowing.sgml">
|
||||
<!entity ole SYSTEM "ole.sgml">
|
||||
<!entity opengl SYSTEM "opengl.sgml">
|
||||
<!entity ddraw SYSTEM "ddraw.sgml">
|
||||
<!entity multimedia SYSTEM "multimedia.sgml">
|
||||
]>
|
||||
|
||||
<book id="index">
|
||||
<bookinfo>
|
||||
<title>Wine Developer's Guide</title>
|
||||
|
||||
<!-- Until we learn how to format this thing nicely,
|
||||
we can't really include it -->
|
||||
<!--authorgroup>
|
||||
<author>
|
||||
<firstname>Uwe</firstname>
|
||||
<surname>Bonnes</surname>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Jonathan</firstname>
|
||||
<surname>Buzzard</surname>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Zoran</firstname>
|
||||
<surname>Dzelajlija</surname>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Klaas</firstname>
|
||||
<surname>van Gend</surname>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Francois</firstname>
|
||||
<surname>Gouget</surname>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Jon</firstname>
|
||||
<surname>Griffiths</surname>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Albert</firstname>
|
||||
<surname>den Haan</surname>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Mike</firstname>
|
||||
<surname>Hearn</surname>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Ove</firstname>
|
||||
<surname>Kaaven</surname>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Tony</firstname>
|
||||
<surname>Lambregts</surname>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Marcus</firstname>
|
||||
<surname>Meissner</surname>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Gerard</firstname>
|
||||
<surname>Patel</surname>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Dimitrie</firstname>
|
||||
<surname>Paun</surname>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Michele</firstname>
|
||||
<surname>Petrovski</surname>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Eric</firstname>
|
||||
<surname>Pouech</surname>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Douglas</firstname>
|
||||
<surname>Ridgway</surname>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>John</firstname>
|
||||
<surname>Sheets</surname>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Lionel</firstname>
|
||||
<surname>Ulmer</surname>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Ulrich</firstname>
|
||||
<surname>Weigand</surname>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Morten</firstname>
|
||||
<surname>Welinder</surname>
|
||||
</author>
|
||||
</authorgroup-->
|
||||
</bookinfo>
|
||||
|
||||
<part id="part-one">
|
||||
<title>Developing Wine</title>
|
||||
|
||||
&debugger;
|
||||
&debugging;
|
||||
&otherdebug;
|
||||
&codingpractice;
|
||||
&testing;
|
||||
&documentation;
|
||||
</part>
|
||||
|
||||
<part id="part-two">
|
||||
<title>Wine Architecture</title>
|
||||
|
||||
&architecture;
|
||||
&kernel;
|
||||
&graphical;
|
||||
&windowing;
|
||||
&ole;
|
||||
&opengl;
|
||||
&ddraw;
|
||||
&multimedia;
|
||||
</part>
|
||||
</book>
|
|
@ -1,8 +0,0 @@
|
|||
<!doctype Article PUBLIC "-//OASIS//DTD DocBook V3.1//EN" [
|
||||
|
||||
<!entity faq SYSTEM "faq.sgml">
|
||||
]>
|
||||
|
||||
<article class="faq" id="index">
|
||||
&faq;
|
||||
</article>
|
|
@ -1,90 +0,0 @@
|
|||
<!doctype book PUBLIC "-//OASIS//DTD DocBook V3.1//EN" [
|
||||
|
||||
<!entity introduction SYSTEM "introduction.sgml">
|
||||
<!entity getting SYSTEM "getting.sgml">
|
||||
<!entity configuring SYSTEM "configuring.sgml">
|
||||
<!entity registry SYSTEM "registry.sgml">
|
||||
<!entity fonts SYSTEM "fonts.sgml">
|
||||
<!entity printing SYSTEM "printing.sgml">
|
||||
<!entity running SYSTEM "running.sgml">
|
||||
<!entity bugs SYSTEM "bugs.sgml">
|
||||
<!entity glossary SYSTEM "glossary.sgml">
|
||||
]>
|
||||
|
||||
<book id="index">
|
||||
<bookinfo>
|
||||
<title>Wine User Guide</title>
|
||||
<!-- Until we learn how to format this thing nicely,
|
||||
we can't really incude it -->
|
||||
<!--authorgroup>
|
||||
<author>
|
||||
<firstname>Scott</firstname>
|
||||
<surname>Ritchie</surname>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Brian</firstname>
|
||||
<surname>Vincent</surname>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Huw</firstname>
|
||||
<surname>Davies</surname>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Steven</firstname>
|
||||
<surname>Elliott</surname>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Mike</firstname>
|
||||
<surname>Hearn</surname>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>James</firstname>
|
||||
<surname>Juran</surname>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Ove</firstname>
|
||||
<surname>Kaaven</surname>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Alex</firstname>
|
||||
<surname>Korobka</surname>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Bruce</firstname>
|
||||
<surname>Milner</surname>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Andreas</firstname>
|
||||
<surname>Mohr</surname>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Dustin</firstname>
|
||||
<surname>Navea</surname>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Eric</firstname>
|
||||
<surname>Pouech</surname>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Adam</firstname>
|
||||
<surname>Sacarny</surname>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>John</firstname>
|
||||
<surname>Sheets</surname>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Petr</firstname>
|
||||
<surname>Tomasek</surname>
|
||||
</author>
|
||||
</authorgroup-->
|
||||
</bookinfo>
|
||||
|
||||
&introduction;
|
||||
&getting;
|
||||
&configuring;
|
||||
&running;
|
||||
&bugs;
|
||||
&glossary;
|
||||
|
||||
</book>
|
|
@ -1,514 +0,0 @@
|
|||
<chapter id="codingpractice">
|
||||
<title>Coding Practice</title>
|
||||
|
||||
<para>
|
||||
This chapter describes the relevant coding practices in Wine,
|
||||
that you should be aware of before doing any serious development
|
||||
in Wine.
|
||||
</para>
|
||||
<sect1 id="patch-format">
|
||||
<title>Patch Format</title>
|
||||
|
||||
<para>
|
||||
Patches are submitted via email to the Wine patches mailing
|
||||
list, <email>wine-patches@winehq.org</email>. Your patch
|
||||
should include:
|
||||
</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
A meaningful subject (very short description of patch)
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
A long (paragraph) description of what was wrong and what
|
||||
is now better. (recommended)
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
A change log entry (short description of what was
|
||||
changed).
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The patch in <command>diff -u</command> format
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para></para>
|
||||
|
||||
<para>
|
||||
<command>cvs diff -u</command> works great for the common case
|
||||
where a file is edited. However, if you add or remove a file
|
||||
<command>cvs diff</command> will not report that correctly so
|
||||
make sure you explicitly take care of this rare case.
|
||||
</para>
|
||||
<para>
|
||||
For additions simply include them by appending the
|
||||
<command>diff -u /dev/null /my/new/file</command> output of
|
||||
them to any <command>cvs diff -u</command> output you may
|
||||
have. Alternatively, use <command>diff -Nu olddir/
|
||||
newdir/</command> in case of multiple new files to add.
|
||||
</para>
|
||||
<para>
|
||||
For removals, clearly list the files in the description of the
|
||||
patch.
|
||||
</para>
|
||||
<para>
|
||||
Since wine is constantly changing due to development it is
|
||||
strongly recommended that you use cvs for patches, if you
|
||||
cannot use cvs for some reason, you can submit patches against
|
||||
the latest tarball. To do this make a copy of the files that
|
||||
you will be modifying and <command>diff -u</command> against
|
||||
the old file. I.E.
|
||||
</para>
|
||||
<screen>
|
||||
diff -u file.old file.c > file.txt
|
||||
</screen>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="Style-notes">
|
||||
<title>Some notes about style</title>
|
||||
|
||||
<para>
|
||||
There are a few conventions about coding style that have
|
||||
been adopted over the years of development. The rational for
|
||||
these <quote>rules</quote> is explained for each one.
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
No HTML mail, since patches should be in-lined and HTML
|
||||
turns the patch into garbage. Also it is considered bad
|
||||
etiquette as it uglifies the message, and is not viewable
|
||||
by many of the subscribers.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Only one change set per patch. Patches should address only
|
||||
one bug/problem at a time. If a lot of changes need to be
|
||||
made then it is preferred to break it into a series of
|
||||
patches. This makes it easier to find regressions.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Tabs are not forbidden but discouraged. A tab is defined
|
||||
as 8 characters and the usual amount of indentation is 4
|
||||
characters.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
C++ style comments are discouraged since some compilers
|
||||
choke on them.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Commenting out a block of code is usually done by
|
||||
enclosing it in <command>#if 0 ... #endif</command>
|
||||
Statements. For example.
|
||||
</para>
|
||||
<screen>
|
||||
/* note about reason for commenting block */
|
||||
#if 0
|
||||
code
|
||||
code /* comments */
|
||||
code
|
||||
#endif
|
||||
</screen>
|
||||
<para>
|
||||
The reason for using this method is that it does not
|
||||
require that you edit comments that may be inside the
|
||||
block of code.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Patches should be in-lined (if you can configure your
|
||||
email client to not wrap lines), or attached as plain text
|
||||
attachments so they can be read inline. This may mean some
|
||||
more work for you. However it allows others to review your
|
||||
patch easily and decreases the chances of it being
|
||||
overlooked or forgotten.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Code is usually limited to 80 columns. This helps prevent
|
||||
mailers mangling patches by line wrap. Also it generally
|
||||
makes code easier to read.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
If the patch fixes a bug in Bugzilla please provide a link
|
||||
to the bug in the comments of the patch. This will make it
|
||||
easier for the maintainers of Bugzilla.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<sect2 id="Inline-Attachments-with-OE">
|
||||
<title>Inline attachments with Outlook Express</title>
|
||||
<para>
|
||||
Outlook Express is notorious for mangling
|
||||
attachments. Giving the patch a <filename>.txt</filename>
|
||||
extension and attaching will solve the problem for most
|
||||
mailers including Outlook. Also, there is a way to enable
|
||||
Outlook Express to send <filename>.diff</filename>
|
||||
attachments.
|
||||
</para>
|
||||
<para>
|
||||
You need the following two things to make it work.
|
||||
</para>
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
Make sure that <filename>.diff</filename> files have
|
||||
\r\n line ends, because if OE detects that there is no
|
||||
\r\n line endings it switches to quoted-printable format
|
||||
attachments.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Using regedit add key "Content Type"
|
||||
with value "text/plain" to the
|
||||
<filename>.diff</filename> extension under
|
||||
HKEY_CLASSES_ROOT (same as for <filename>.txt</filename>
|
||||
extension). This tells OE to use
|
||||
Content-Type: text/plain instead of
|
||||
application/octet-stream.
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
<para>
|
||||
Item #1 is important. After you hit the "Send" button, go to
|
||||
"Outbox" and using "Properties" verify the message source to
|
||||
make sure that the mail has the correct format. You might want
|
||||
to send several test emails to yourself too.
|
||||
</para>
|
||||
</sect2>
|
||||
<sect2 id="Alexandre-Bottom-Line">
|
||||
<title>Alexandre's Bottom Line</title>
|
||||
<para>
|
||||
<quote>The basic rules are: no attachments, no MIME crap, no
|
||||
line wrapping, a single patch per mail. Basically if I can't
|
||||
do <command>"cat raw_mail | patch -p0"</command> it's in the
|
||||
wrong format.</quote>
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="patch-quality">
|
||||
<title>Quality Assurance</title>
|
||||
|
||||
<para>
|
||||
(Or, "How do I get Alexandre to apply my patch quickly so I
|
||||
can build on it and it will not go stale?")
|
||||
</para>
|
||||
<para>
|
||||
Make sure your patch applies to the current CVS head
|
||||
revisions. If a bunch of patches are committed to CVS that may
|
||||
affect whether your patch will apply cleanly then verify that
|
||||
your patch does apply! <command>cvs update</command> is your
|
||||
friend!
|
||||
</para>
|
||||
<para>
|
||||
Save yourself some embarrassment and run your patched code
|
||||
against more than just your current test example. Experience
|
||||
will tell you how much effort to apply here. If there are
|
||||
any conformance tests for the code you're working on, run them
|
||||
and make sure they still pass after your patch is applied. Running
|
||||
tests can be done by running <command>make test</command>. You may
|
||||
need to run <command>make testclean</command> to undo the results
|
||||
of a previous test run. See the <quote>testing</quote> guide for
|
||||
more details on Wine's conformance tests.
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
<sect1 id="porting">
|
||||
<title>Porting Wine to new Platforms</title>
|
||||
<para>
|
||||
This document provides a few tips on porting Wine to your
|
||||
favorite (UNIX-based) operating system.
|
||||
</para>
|
||||
|
||||
<sect2>
|
||||
<title>
|
||||
Why <symbol>#ifdef MyOS</symbol> is probably a mistake.
|
||||
</title>
|
||||
|
||||
<para>
|
||||
Operating systems change. Maybe yours doesn't have the
|
||||
<filename>foo.h</filename> header, but maybe a future
|
||||
version will have it. If you want to <symbol>#include
|
||||
<foo.h></symbol>, it doesn't matter what operating
|
||||
system you are using; it only matters whether
|
||||
<filename>foo.h</filename> is there.
|
||||
</para>
|
||||
<para>
|
||||
Furthermore, operating systems change names or "fork" into
|
||||
several ones. An <symbol>#ifdef MyOs</symbol> will break
|
||||
over time.
|
||||
</para>
|
||||
<para>
|
||||
If you use the feature of <command>autoconf</command> -- the
|
||||
Gnu auto-configuration utility -- wisely, you will help
|
||||
future porters automatically because your changes will test
|
||||
for <emphasis>features</emphasis>, not names of operating
|
||||
systems. A feature can be many things:
|
||||
</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
existence of a header file
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
existence of a library function
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
existence of libraries
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
bugs in header files, library functions, the compiler, ...
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<para>
|
||||
You will need Gnu Autoconf, which you can get from your
|
||||
friendly Gnu mirror. This program takes Wine's
|
||||
<filename>configure.ac</filename> file and produces a
|
||||
<filename>configure</filename> shell script that users use
|
||||
to configure Wine to their system.
|
||||
</para>
|
||||
<para>
|
||||
There <emphasis>are</emphasis> exceptions to the "avoid
|
||||
<symbol>#ifdef MyOS</symbol>" rule. Wine, for example, needs
|
||||
the internals of the signal stack -- that cannot easily be
|
||||
described in terms of features. Moreover, you cannot use
|
||||
<filename>autoconf</filename>'s <symbol>HAVE_*</symbol>
|
||||
symbols in Wine's headers, as these may be used by Winelib
|
||||
users who may not be using a <filename>configure</filename>
|
||||
script.
|
||||
</para>
|
||||
<para>
|
||||
Let's now turn to specific porting problems and how to solve
|
||||
them.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>
|
||||
MyOS doesn't have the <filename>foo.h</filename> header!
|
||||
</title>
|
||||
|
||||
<para>
|
||||
This first step is to make <command>autoconf</command> check
|
||||
for this header. In <filename>configure.in</filename> you
|
||||
add a segment like this in the section that checks for
|
||||
header files (search for "header files"):
|
||||
</para>
|
||||
<programlisting>
|
||||
AC_CHECK_HEADER(foo.h, AC_DEFINE(HAVE_FOO_H))
|
||||
</programlisting>
|
||||
<para>
|
||||
If your operating system supports a header file with the
|
||||
same contents but a different name, say
|
||||
<filename>bar.h</filename>, add a check for that also.
|
||||
</para>
|
||||
<para>
|
||||
Now you can change
|
||||
</para>
|
||||
<programlisting>
|
||||
#include <foo.h>
|
||||
</programlisting>
|
||||
<para>
|
||||
to
|
||||
</para>
|
||||
<programlisting>
|
||||
#ifdef HAVE_FOO_H
|
||||
#include <foo.h>
|
||||
#elif defined (HAVE_BAR_H)
|
||||
#include <bar.h>
|
||||
#endif
|
||||
</programlisting>
|
||||
<para>
|
||||
If your system doesn't have a corresponding header file even
|
||||
though it has the library functions being used, you might
|
||||
have to add an <symbol>#else</symbol> section to the
|
||||
conditional. Avoid this if you can.
|
||||
</para>
|
||||
<para>
|
||||
You will also need to add <symbol>#undef HAVE_FOO_H</symbol>
|
||||
(etc.) to <filename>include/config.h.in</filename>
|
||||
</para>
|
||||
<para>
|
||||
Finish up with <command>make configure</command> and
|
||||
<command>./configure</command>.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>
|
||||
MyOS doesn't have the <function>bar</function> function!
|
||||
</title>
|
||||
|
||||
<para>
|
||||
A typical example of this is the <function>memmove</function>
|
||||
function. To solve this problem you would add
|
||||
<function>memmove</function> to the list of functions that
|
||||
<command>autoconf</command> checks for. In
|
||||
<filename>configure.in</filename> you search for
|
||||
<function>AC_CHECK_FUNCS</function> and add
|
||||
<function>memmove</function>. (You will notice that someone
|
||||
already did this for this particular function.)
|
||||
</para>
|
||||
<para>
|
||||
Secondly, you will also need to add
|
||||
<symbol>#undef HAVE_BAR</symbol> to
|
||||
<filename>include/config.h.in</filename>
|
||||
</para>
|
||||
<para>
|
||||
The next step depends on the nature of the missing function.
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>Case 1:</term>
|
||||
<listitem>
|
||||
<para>
|
||||
It's easy to write a complete implementation of the
|
||||
function. (<function>memmove</function> belongs to
|
||||
this case.)
|
||||
</para>
|
||||
<para>
|
||||
You add your implementation in
|
||||
<filename>misc/port.c</filename> surrounded by
|
||||
<symbol>#ifndef HAVE_MEMMOVE</symbol> and
|
||||
<symbol>#endif</symbol>.
|
||||
</para>
|
||||
<para>
|
||||
You might have to add a prototype for your function.
|
||||
If so, <filename>include/miscemu.h</filename> might be
|
||||
the place. Don't forget to protect that definition by
|
||||
<symbol>#ifndef HAVE_MEMMOVE</symbol> and
|
||||
<symbol>#endif</symbol> also!
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>Case 2:</term>
|
||||
<listitem>
|
||||
<para>
|
||||
A general implementation is hard, but Wine is only
|
||||
using a special case.
|
||||
</para>
|
||||
<para>
|
||||
An example is the various <function>wait</function>
|
||||
calls used in <function>SIGNAL_child</function> from
|
||||
<filename>loader/signal.c</filename>. Here we have a
|
||||
multi-branch case on features:
|
||||
</para>
|
||||
<programlisting>
|
||||
#ifdef HAVE_THIS
|
||||
...
|
||||
#elif defined (HAVE_THAT)
|
||||
...
|
||||
#elif defined (HAVE_SOMETHING_ELSE)
|
||||
...
|
||||
#endif
|
||||
</programlisting>
|
||||
<para>
|
||||
Note that this is very different from testing on
|
||||
operating systems. If a new version of your operating
|
||||
systems comes out and adds a new function, this code
|
||||
will magically start using it.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
<para>
|
||||
Finish up with <command>make configure</command> and
|
||||
<command>./configure</command>.
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="adding-languages">
|
||||
<title>Adding New Languages</title>
|
||||
|
||||
<para>
|
||||
This file documents the necessary procedure for adding a new
|
||||
language to the list of languages that Wine can display system
|
||||
menus and forms in. Adding new translations is not hard as it
|
||||
requires no programming knowledge or special skills.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Language dependent resources reside in files
|
||||
named <filename>somefile_Xx.rc</filename> or
|
||||
<filename>Xx.rc</filename>, where <literal>Xx</literal>
|
||||
is your language abbreviation (look for it in
|
||||
<filename>include/winnls.h</filename>). These are included
|
||||
in a master file named <filename>somefile.rc</filename> or
|
||||
<filename>rsrc.rc</filename>, located in the same
|
||||
directory as the language files.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
To add a new language to one of these resources you
|
||||
need to make a copy of the English resource (located
|
||||
in the <filename>somefile_En.rc</filename> file) over to
|
||||
your <filename>somefile_Xx.rc</filename> file, include this
|
||||
file in the master <filename>somefile.rc</filename> file,
|
||||
and edit the new file to translate the English text.
|
||||
You may also need to rearrange some of the controls
|
||||
to better fit the newly translated strings. Test your changes
|
||||
to make sure they properly layout on the screen.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In menus, the character "&" means that the next
|
||||
character will be highlighted and that pressing that
|
||||
letter will select the item. You should place these
|
||||
"&" characters suitably for your language, not just
|
||||
copy the positions from English. In particular,
|
||||
items within one menu should have different highlighted
|
||||
letters.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
To get a list of the files that need translating,
|
||||
run the following command in the root of your Wine tree:
|
||||
<command>find -name "*En.rc"</command>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
When adding a new language, also make sure the parameters
|
||||
defined in <filename>./dlls/kernel/nls/*.nls</filename>
|
||||
fit your local habits and language.
|
||||
</para>
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
||||
<!-- Keep this comment at the end of the file
|
||||
Local variables:
|
||||
mode: sgml
|
||||
sgml-parent-document:("wine-devel.sgml" "set" "book" "part" "chapter" "")
|
||||
End:
|
||||
-->
|
|
@ -1,40 +0,0 @@
|
|||
<chapter>
|
||||
<title>Graphical modules</title>
|
||||
<sect1>
|
||||
<title>GDI Module</title>
|
||||
|
||||
<sect2>
|
||||
<title>X Windows System interface</title>
|
||||
|
||||
<para>
|
||||
The X libraries used to implement X clients (such as Wine)
|
||||
do not work properly if multiple threads access the same
|
||||
display concurrently. It is possible to compile the X
|
||||
libraries to perform their own synchronization (initiated
|
||||
by calling <function>XInitThreads()</function>). However,
|
||||
Wine does not use this approach. Instead Wine performs its
|
||||
own synchronization using the
|
||||
<function>wine_tsx11_lock()</function> / <function>wine_tsx11_unlock()</function>
|
||||
functions. This locking protects library access
|
||||
with a critical section, and also arranges things so that
|
||||
X libraries compiled without <option>-D_REENTRANT</option>
|
||||
(eg. with global <varname>errno</varname> variable) will
|
||||
work with Wine.
|
||||
</para>
|
||||
<para>
|
||||
In the past, all calls to X used to go through a wrapper called
|
||||
<function>TSX...()</function> (for "Thread Safe X ...").
|
||||
While it is still being used in the code, it's inefficient
|
||||
as the lock is potentially aquired and released unnecessarily.
|
||||
New code should explicitly aquire the lock.
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
||||
<!-- Keep this comment at the end of the file
|
||||
Local variables:
|
||||
mode: sgml
|
||||
sgml-parent-document:("wine-devel.sgml" "set" "book" "part" "chapter" "")
|
||||
End:
|
||||
-->
|
File diff suppressed because it is too large
Load diff
|
@ -1,685 +0,0 @@
|
|||
<chapter id="otherdebug">
|
||||
<title>Other debugging techniques</title>
|
||||
<sect1 id="hardware-trace">
|
||||
<title>Doing A Hardware Trace</title>
|
||||
|
||||
<para>
|
||||
The primary reason to do this is to reverse engineer a
|
||||
hardware device for which you don't have documentation, but
|
||||
can get to work under Wine.
|
||||
</para>
|
||||
<para>
|
||||
This lot is aimed at parallel port devices, and in particular
|
||||
parallel port scanners which are now so cheap they are
|
||||
virtually being given away. The problem is that few
|
||||
manufactures will release any programming information which
|
||||
prevents drivers being written for Sane, and the traditional
|
||||
technique of using DOSemu to produce the traces does not work
|
||||
as the scanners invariably only have drivers for Windows.
|
||||
</para>
|
||||
<para>
|
||||
Presuming that you have compiled and installed wine the first
|
||||
thing to do is is to enable direct hardware access to your
|
||||
parallel port. To do this edit <filename>config</filename>
|
||||
(usually in <filename>~/.wine/</filename>) and in the
|
||||
ports section add the following two lines
|
||||
</para>
|
||||
<programlisting>
|
||||
read=0x378,0x379,0x37a,0x37c,0x77a
|
||||
write=0x378,x379,0x37a,0x37c,0x77a
|
||||
</programlisting>
|
||||
<para>
|
||||
This adds the necessary access required for SPP/PS2/EPP/ECP
|
||||
parallel port on LPT1. You will need to adjust these number
|
||||
accordingly if your parallel port is on LPT2 or LPT0.
|
||||
</para>
|
||||
<para>
|
||||
When starting wine use the following command line, where
|
||||
<literal>XXXX</literal> is the program you need to run in
|
||||
order to access your scanner, and <literal>YYYY</literal> is
|
||||
the file your trace will be stored in:
|
||||
</para>
|
||||
<programlisting>
|
||||
WINEDEBUG=+io wine XXXX 2> >(sed 's/^[^:]*:io:[^ ]* //' > YYYY)
|
||||
</programlisting>
|
||||
<para>
|
||||
You will need large amounts of hard disk space (read hundreds
|
||||
of megabytes if you do a full page scan), and for reasonable
|
||||
performance a really fast processor and lots of RAM.
|
||||
</para>
|
||||
<para>
|
||||
You will need to postprocess the output into a more manageable
|
||||
format, using the <command>shrink</command> program. First
|
||||
you need to compile the source (which is located at the end of
|
||||
this section):
|
||||
<programlisting>
|
||||
cc shrink.c -o shrink
|
||||
</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
Use the <command>shrink</command> program to reduce the
|
||||
physical size of the raw log as follows:
|
||||
</para>
|
||||
<programlisting>
|
||||
cat log | shrink > log2
|
||||
</programlisting>
|
||||
<para>
|
||||
The trace has the basic form of
|
||||
</para>
|
||||
<programlisting>
|
||||
XXXX > YY @ ZZZZ:ZZZZ
|
||||
</programlisting>
|
||||
<para>
|
||||
where <literal>XXXX</literal> is the port in hexadecimal being
|
||||
accessed, <literal>YY</literal> is the data written (or read)
|
||||
from the port, and <literal>ZZZZ:ZZZZ</literal> is the address
|
||||
in memory of the instruction that accessed the port. The
|
||||
direction of the arrow indicates whether the data was written
|
||||
or read from the port.
|
||||
</para>
|
||||
<programlisting>
|
||||
> data was written to the port
|
||||
< data was read from the port
|
||||
</programlisting>
|
||||
<para>
|
||||
My basic tip for interpreting these logs is to pay close
|
||||
attention to the addresses of the IO instructions. Their
|
||||
grouping and sometimes proximity should reveal the presence of
|
||||
subroutines in the driver. By studying the different versions
|
||||
you should be able to work them out. For example consider the
|
||||
following section of trace from my UMAX Astra 600P
|
||||
</para>
|
||||
<programlisting>
|
||||
0x378 > 55 @ 0297:01ec
|
||||
0x37a > 05 @ 0297:01f5
|
||||
0x379 < 8f @ 0297:01fa
|
||||
0x37a > 04 @ 0297:0211
|
||||
0x378 > aa @ 0297:01ec
|
||||
0x37a > 05 @ 0297:01f5
|
||||
0x379 < 8f @ 0297:01fa
|
||||
0x37a > 04 @ 0297:0211
|
||||
0x378 > 00 @ 0297:01ec
|
||||
0x37a > 05 @ 0297:01f5
|
||||
0x379 < 8f @ 0297:01fa
|
||||
0x37a > 04 @ 0297:0211
|
||||
0x378 > 00 @ 0297:01ec
|
||||
0x37a > 05 @ 0297:01f5
|
||||
0x379 < 8f @ 0297:01fa
|
||||
0x37a > 04 @ 0297:0211
|
||||
0x378 > 00 @ 0297:01ec
|
||||
0x37a > 05 @ 0297:01f5
|
||||
0x379 < 8f @ 0297:01fa
|
||||
0x37a > 04 @ 0297:0211
|
||||
0x378 > 00 @ 0297:01ec
|
||||
0x37a > 05 @ 0297:01f5
|
||||
0x379 < 8f @ 0297:01fa
|
||||
0x37a > 04 @ 0297:0211
|
||||
</programlisting>
|
||||
<para>
|
||||
As you can see there is a repeating structure starting at
|
||||
address <literal>0297:01ec</literal> that consists of four io
|
||||
accesses on the parallel port. Looking at it the first io
|
||||
access writes a changing byte to the data port the second
|
||||
always writes the byte <literal>0x05</literal> to the control
|
||||
port, then a value which always seems to
|
||||
<literal>0x8f</literal> is read from the status port at which
|
||||
point a byte <literal>0x04</literal> is written to the control
|
||||
port. By studying this and other sections of the trace we can
|
||||
write a C routine that emulates this, shown below with some
|
||||
macros to make reading/writing on the parallel port easier to
|
||||
read.
|
||||
</para>
|
||||
<programlisting>
|
||||
#define r_dtr(x) inb(x)
|
||||
#define r_str(x) inb(x+1)
|
||||
#define r_ctr(x) inb(x+2)
|
||||
#define w_dtr(x,y) outb(y, x)
|
||||
#define w_str(x,y) outb(y, x+1)
|
||||
#define w_ctr(x,y) outb(y, x+2)
|
||||
|
||||
/* Seems to be sending a command byte to the scanner */
|
||||
int udpp_put(int udpp_base, unsigned char command)
|
||||
{
|
||||
int loop, value;
|
||||
|
||||
w_dtr(udpp_base, command);
|
||||
w_ctr(udpp_base, 0x05);
|
||||
|
||||
for (loop=0; loop < 10; loop++)
|
||||
if ((value = r_str(udpp_base)) & 0x80)
|
||||
{
|
||||
w_ctr(udpp_base, 0x04);
|
||||
return value & 0xf8;
|
||||
}
|
||||
|
||||
return (value & 0xf8) | 0x01;
|
||||
}
|
||||
</programlisting>
|
||||
<para>
|
||||
For the UMAX Astra 600P only seven such routines exist (well
|
||||
14 really, seven for SPP and seven for EPP). Whether you
|
||||
choose to disassemble the driver at this point to verify the
|
||||
routines is your own choice. If you do, the address from the
|
||||
trace should help in locating them in the disassembly.
|
||||
</para>
|
||||
<para>
|
||||
You will probably then find it useful to write a script/perl/C
|
||||
program to analyse the logfile and decode them futher as this
|
||||
can reveal higher level grouping of the low level routines.
|
||||
For example from the logs from my UMAX Astra 600P when decoded
|
||||
further reveal (this is a small snippet)
|
||||
</para>
|
||||
<programlisting>
|
||||
start:
|
||||
put: 55 8f
|
||||
put: aa 8f
|
||||
put: 00 8f
|
||||
put: 00 8f
|
||||
put: 00 8f
|
||||
put: c2 8f
|
||||
wait: ff
|
||||
get: af,87
|
||||
wait: ff
|
||||
get: af,87
|
||||
end: cc
|
||||
start:
|
||||
put: 55 8f
|
||||
put: aa 8f
|
||||
put: 00 8f
|
||||
put: 03 8f
|
||||
put: 05 8f
|
||||
put: 84 8f
|
||||
wait: ff
|
||||
</programlisting>
|
||||
<para>
|
||||
From this it is easy to see that <varname>put</varname>
|
||||
routine is often grouped together in five successive calls
|
||||
sending information to the scanner. Once these are understood
|
||||
it should be possible to process the logs further to show the
|
||||
higher level routines in an easy to see format. Once the
|
||||
highest level format that you can derive from this process is
|
||||
understood, you then need to produce a series of scans varying
|
||||
only one parameter between them, so you can discover how to
|
||||
set the various parameters for the scanner.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The following is the <filename>shrink.c</filename> program:
|
||||
<programlisting>
|
||||
/* Copyright David Campbell <campbell@torque.net> */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int main (void)
|
||||
{
|
||||
char buff[256], lastline[256] = "";
|
||||
int count = 0;
|
||||
|
||||
while (!feof (stdin))
|
||||
{
|
||||
fgets (buff, sizeof (buff), stdin);
|
||||
if (strcmp (buff, lastline))
|
||||
{
|
||||
if (count > 1)
|
||||
printf ("# Last line repeated %i times #\n", count);
|
||||
printf ("%s", buff);
|
||||
strcpy (lastline, buff);
|
||||
count = 1;
|
||||
}
|
||||
else count++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
</programlisting>
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="undoc-func">
|
||||
<title>Understanding undocumented APIs</title>
|
||||
|
||||
<para>
|
||||
Some background: On the i386 class of machines, stack entries are
|
||||
usually dword (4 bytes) in size, little-endian. The stack grows
|
||||
downward in memory. The stack pointer, maintained in the
|
||||
<literal>esp</literal> register, points to the last valid entry;
|
||||
thus, the operation of pushing a value onto the stack involves
|
||||
decrementing <literal>esp</literal> and then moving the value into
|
||||
the memory pointed to by <literal>esp</literal>
|
||||
(i.e., <literal>push p</literal> in assembly resembles
|
||||
<literal>*(--esp) = p;</literal> in C). Removing (popping)
|
||||
values off the stack is the reverse (i.e., <literal>pop p</literal>
|
||||
corresponds to <literal>p = *(esp++);</literal> in C).
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In the <literal>stdcall</literal> calling convention, arguments are
|
||||
pushed onto the stack right-to-left. For example, the C call
|
||||
<function>myfunction(40, 20, 70, 30);</function> is expressed in
|
||||
Intel assembly as:
|
||||
<screen>
|
||||
push 30
|
||||
push 70
|
||||
push 20
|
||||
push 40
|
||||
call myfunction
|
||||
</screen>
|
||||
The called function is responsible for removing the arguments
|
||||
off the stack. Thus, before the call to myfunction, the
|
||||
stack would look like:
|
||||
<screen>
|
||||
[local variable or temporary]
|
||||
[local variable or temporary]
|
||||
30
|
||||
70
|
||||
20
|
||||
esp -> 40
|
||||
</screen>
|
||||
After the call returns, it should look like:
|
||||
<screen>
|
||||
[local variable or temporary]
|
||||
esp -> [local variable or temporary]
|
||||
</screen>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
To restore the stack to this state, the called function must know how
|
||||
many arguments to remove (which is the number of arguments it takes).
|
||||
This is a problem if the function is undocumented.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
One way to attempt to document the number of arguments each function
|
||||
takes is to create a wrapper around that function that detects the
|
||||
stack offset. Essentially, each wrapper assumes that the function will
|
||||
take a large number of arguments. The wrapper copies each of these
|
||||
arguments into its stack, calls the actual function, and then calculates
|
||||
the number of arguments by checking esp before and after the call.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The main problem with this scheme is that the function must actually
|
||||
be called from another program. Many of these functions are seldom
|
||||
used. An attempt was made to aggressively query each function in a
|
||||
given library (<filename>ntdll.dll</filename>) by passing 64 arguments,
|
||||
all 0, to each function. Unfortunately, Windows NT quickly goes to a
|
||||
blue screen of death, even if the program is run from a
|
||||
non-administrator account.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Another method that has been much more successful is to attempt to
|
||||
figure out how many arguments each function is removing from the
|
||||
stack. This instruction, <literal>ret hhll</literal> (where
|
||||
<symbol>hhll</symbol> is the number of bytes to remove, i.e. the
|
||||
number of arguments times 4), contains the bytes
|
||||
<literal>0xc2 ll hh</literal> in memory. It is a reasonable
|
||||
assumption that few, if any, functions take more than 16 arguments;
|
||||
therefore, simply searching for
|
||||
<literal>hh == 0 && ll < 0x40</literal> starting from the
|
||||
address of a function yields the correct number of arguments most
|
||||
of the time.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Of course, this is not without errors. <literal>ret 00ll</literal>
|
||||
is not the only instruction that can have the byte sequence
|
||||
<literal>0xc2 ll 0x0</literal>; for example,
|
||||
<literal>push 0x000040c2</literal> has the byte sequence
|
||||
<literal>0x68 0xc2 0x40 0x0 0x0</literal>, which matches
|
||||
the above. Properly, the utility should look for this sequence
|
||||
only on an instruction boundary; unfortunately, finding
|
||||
instruction boundaries on an i386 requires implementing a full
|
||||
disassembler -- quite a daunting task. Besides, the probability
|
||||
of having such a byte sequence that is not the actual return
|
||||
instruction is fairly low.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Much more troublesome is the non-linear flow of a function. For
|
||||
example, consider the following two functions:
|
||||
<screen>
|
||||
somefunction1:
|
||||
jmp somefunction1_impl
|
||||
|
||||
somefunction2:
|
||||
ret 0004
|
||||
|
||||
somefunction1_impl:
|
||||
ret 0008
|
||||
</screen>
|
||||
In this case, we would incorrectly detect both
|
||||
<function>somefunction1</function> and
|
||||
<function>somefunction2</function> as taking only a single
|
||||
argument, whereas <function>somefunction1</function> really
|
||||
takes two arguments.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
With these limitations in mind, it is possible to implement
|
||||
more stubs
|
||||
in Wine and, eventually, the functions themselves.
|
||||
</para>
|
||||
</sect1>
|
||||
<sect1>
|
||||
<title>How to do regression testing using CVS</title>
|
||||
|
||||
<para>
|
||||
A problem that can happen sometimes is 'it used to work
|
||||
before, now it doesn't anymore...'. Here is a step by step
|
||||
procedure to try to pinpoint when the problem occurred. This
|
||||
is <emphasis>NOT</emphasis> for casual users.
|
||||
</para>
|
||||
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
Get the <quote>full CVS</quote> archive from winehq. This
|
||||
archive is the CVS tree but with the tags controlling the
|
||||
versioning system. It's a big file (> 40 meg) with a name
|
||||
like full-cvs-<last update date> (it's more than 100mb
|
||||
when uncompressed, you can't very well do this with
|
||||
small, old computers or slow Internet connections).
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
untar it into a repository directory:
|
||||
<screen>
|
||||
cd /home/gerard
|
||||
tar -zxf full-cvs-2003-08-18.tar.gz
|
||||
mv wine repository
|
||||
</screen>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
extract a new destination directory. This directory must
|
||||
not be in a subdirectory of the repository else
|
||||
<command>cvs</command> will think it's part of the
|
||||
repository and deny you an extraction in the repository:
|
||||
<screen>
|
||||
cd /home/gerard
|
||||
mv wine wine_current (-> this protects your current wine sandbox, if any)
|
||||
export CVSROOT=/home/gerard/repository
|
||||
cvs -d $CVSROOT checkout wine
|
||||
</screen>
|
||||
</para>
|
||||
<para>
|
||||
Note that it's not possible to do a checkout at a given
|
||||
date; you always do the checkout for the last date where
|
||||
the full-cvs-xxx snapshot was generated.
|
||||
</para>
|
||||
<para>
|
||||
Note also that it is possible to do all this with a direct
|
||||
CVS connection, of course. The full CVS file method is less
|
||||
painful for the WineHQ CVS server and probably a bit faster
|
||||
if you don't have a very good net connection.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
you will have now in the <filename>~/wine</filename>
|
||||
directory an image of the CVS tree, on the client side.
|
||||
Now update this image to the date you want:
|
||||
<screen>
|
||||
cd /home/gerard/wine
|
||||
cvs update -PAd -D "2004-08-23 CDT"
|
||||
</screen>
|
||||
</para>
|
||||
<para>
|
||||
The date format is <literal>YYYY-MM-DD HH:MM:SS</literal>.
|
||||
Using the CST date format ensure that you will be able to
|
||||
extract patches in a way that will be compatible with the
|
||||
wine-cvs archive
|
||||
<ulink url="http://www.winehq.org/hypermail/wine-cvs">
|
||||
http://www.winehq.org/hypermail/wine-cvs</ulink>
|
||||
</para>
|
||||
<para>
|
||||
Many messages will inform you that more recent files have
|
||||
been deleted to set back the client cvs tree to the date
|
||||
you asked, for example:
|
||||
<screen>
|
||||
cvs update: tsx11/ts_xf86dga2.c is no longer in the repository
|
||||
</screen>
|
||||
</para>
|
||||
<para>
|
||||
<command>cvs update</command> is not limited to upgrade to
|
||||
a <emphasis>newer</emphasis> version as I have believed for
|
||||
far too long :-(
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Now proceed as for a normal update:
|
||||
</para>
|
||||
<screen>
|
||||
./configure
|
||||
make depend && make
|
||||
</screen>
|
||||
<para>
|
||||
If any non-programmer reads this, the fastest method to
|
||||
get at the point where the problem occurred is to use a
|
||||
binary search, that is, if the problem occurred in 1999,
|
||||
start at mid-year, then is the problem is already here,
|
||||
back to 1st April, if not, to 1st October, and so on.
|
||||
</para>
|
||||
<para>
|
||||
If you have lot of hard disk free space (a full compile
|
||||
currently takes 400 Mb), copy the oldest known working
|
||||
version before updating it, it will save time if you need
|
||||
to go back. (it's better to <command>make
|
||||
distclean</command> before going back in time, so you
|
||||
have to make everything if you don't backup the older
|
||||
version)
|
||||
</para>
|
||||
<para>
|
||||
When you have found the day where the problem happened,
|
||||
continue the search using the wine-cvs archive (sorted by
|
||||
date) and a more precise cvs update including hour,
|
||||
minute, second:
|
||||
<screen>
|
||||
cvs update -PAd -D "2004-08-23 15:17:25 CDT"
|
||||
</screen>
|
||||
This will allow you to find easily the exact patch that
|
||||
did it.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
If you find the patch that is the cause of the problem,
|
||||
you have almost won; report about it to
|
||||
<ulink url="http://bugs.winehq.org/">Wine Bugzilla</ulink>
|
||||
or subscribe to wine-devel and post it there. There is a
|
||||
chance that the author will jump in to suggest a fix; or
|
||||
there is always the possibility to look hard at the patch
|
||||
until it is coerced to reveal where is the bug :-)
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
</sect1>
|
||||
<sect1>
|
||||
<title>Which code has been tested?</title>
|
||||
<para>
|
||||
Deciding what code should be tested next can be a difficult
|
||||
decision. And in any given project, there is always code that
|
||||
isn't tested where bugs could be lurking. This section goes
|
||||
over how to identify these sections using a tool called gcov.
|
||||
</para>
|
||||
<para>
|
||||
To use gcov on wine, do the following:
|
||||
</para>
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
In order to activate code coverage in the wine source code,
|
||||
when running <command>make</command> set
|
||||
<literal>CFLAGS</literal> like so <command>make
|
||||
CFLAGS="-fprofile-arcs -ftest-coverage"</command>. Note that
|
||||
this can be done at any directory level. Since compile
|
||||
and run time are significantly increased by these flags, you
|
||||
may want to only use these flags inside a given dll directory.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Run any application or test suite.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Run gcov on the file which you would like to know more
|
||||
about code coverage.
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
<para>
|
||||
The following is an example situation when using gcov to
|
||||
determine the coverage of a file could be helpful. We'll use
|
||||
the <filename>dlls/lzexpand/lzexpand_main.c.</filename> file.
|
||||
At one time the code in this file was not fully tested (as it
|
||||
may still be). For example at the time of this writing, the
|
||||
function <function>LZOpenFileA</function> had the following
|
||||
lines in it:
|
||||
<screen>
|
||||
if ((mode&~0x70)!=OF_READ)
|
||||
return fd;
|
||||
if (fd==HFILE_ERROR)
|
||||
return HFILE_ERROR;
|
||||
cfd=LZInit(fd);
|
||||
if ((INT)cfd <= 0) return fd;
|
||||
return cfd;
|
||||
</screen>
|
||||
Currently there are a few tests written to test this function;
|
||||
however, these tests don't check that everything is correct.
|
||||
For instance, <constant>HFILE_ERROR</constant> may be the wrong
|
||||
error code to return. Using gcov and directed tests, we can
|
||||
validate the correctness of this line of code. First, we see
|
||||
what has been tested already by running gcov on the file.
|
||||
To do this, do the following:
|
||||
<screen>
|
||||
cvs checkout wine
|
||||
mkdir build
|
||||
cd build
|
||||
../wine/configure
|
||||
make depend && make CFLAGS="-fprofile-arcs -ftest-coverage"
|
||||
cd dlls/lxexpand/tests
|
||||
make test
|
||||
cd ..
|
||||
gcov ../../../wine/dlls/lzexpand/lzexpand_main.c
|
||||
0.00% of 3 lines executed in file ../../../wine/include/wine/unicode.h
|
||||
Creating unicode.h.gcov.
|
||||
0.00% of 4 lines executed in file /usr/include/ctype.h
|
||||
Creating ctype.h.gcov.
|
||||
0.00% of 6 lines executed in file /usr/include/bits/string2.h
|
||||
Creating string2.h.gcov.
|
||||
100.00% of 3 lines executed in file ../../../wine/include/winbase.h
|
||||
Creating winbase.h.gcov.
|
||||
50.83% of 240 lines executed in file ../../../wine/dlls/lzexpand/lzexpand_main.c
|
||||
Creating lzexpand_main.c.gcov.
|
||||
less lzexpand_main.c.gcov
|
||||
</screen>
|
||||
Note that there is more output, but only output of gcov is
|
||||
shown. The output file
|
||||
<filename>lzexpand_main.c.gcov</filename> looks like this.
|
||||
<screen>
|
||||
9: 545: if ((mode&~0x70)!=OF_READ)
|
||||
6: 546: return fd;
|
||||
3: 547: if (fd==HFILE_ERROR)
|
||||
#####: 548: return HFILE_ERROR;
|
||||
3: 549: cfd=LZInit(fd);
|
||||
3: 550: if ((INT)cfd <= 0) return fd;
|
||||
3: 551: return cfd;
|
||||
</screen>
|
||||
<command>gcov</command> output consists of three components:
|
||||
the number of times a line was run, the line number, and the
|
||||
actual text of the line. Note: If a line is optimized out by
|
||||
the compiler, it will appear as if it was never run. The line
|
||||
of code which returns <constant>HFILE_ERROR</constant> is
|
||||
never executed (and it is highly unlikely that it is optimized
|
||||
out), so we don't know if it is correct. In order to validate
|
||||
this line, there are two parts of this process. First we must
|
||||
write the test. Please see <xref linkend="testing"> to
|
||||
learn more about writing tests. We insert the following lines
|
||||
into a test case:
|
||||
<screen>
|
||||
INT file;
|
||||
|
||||
/* Check for nonexistent file */
|
||||
file = LZOpenFile("badfilename_", &test, OF_READ);
|
||||
ok(file == LZERROR_BADINHANDLE,
|
||||
"LZOpenFile succeeded on nonexistent file\n");
|
||||
LZClose(file);
|
||||
</screen>
|
||||
Once we add in this test case, we now want to know if the line
|
||||
in question is run by this test and works as expected. You
|
||||
should be in the same directory as you left off in the previous
|
||||
command example. The only difference is that we have to remove
|
||||
the <filename>*.da</filename> files in order to start the
|
||||
count over (if we leave the files than the number of times the
|
||||
line is run is just added, e.g. line 545 below would be run 19 times)
|
||||
and we remove the <filename>*.gcov</filename> files because
|
||||
they are out of date and need to be recreated.
|
||||
</para>
|
||||
<screen>
|
||||
rm *.da *.gcov
|
||||
cd tests
|
||||
make
|
||||
make test
|
||||
cd ..
|
||||
gcov ../../../wine/dlls/lzexpand/lzexpand_main.c
|
||||
0.00% of 3 lines executed in file ../../../wine/include/wine/unicode.h
|
||||
Creating unicode.h.gcov.
|
||||
0.00% of 4 lines executed in file /usr/include/ctype.h
|
||||
Creating ctype.h.gcov.
|
||||
0.00% of 6 lines executed in file /usr/include/bits/string2.h
|
||||
Creating string2.h.gcov.
|
||||
100.00% of 3 lines executed in file ../../../wine/include/winbase.h
|
||||
Creating winbase.h.gcov.
|
||||
51.67% of 240 lines executed in file ../../../wine/dlls/lzexpand/lzexpand_main.c
|
||||
Creating lzexpand_main.c.gcov.
|
||||
less lzexpand_main.c.gcov
|
||||
</screen>
|
||||
<para>
|
||||
Note that there is more output, but only output of gcov is
|
||||
shown. The output file
|
||||
<filename>lzexpand_main.c.gcov</filename> looks like this.
|
||||
</para>
|
||||
<screen>
|
||||
10: 545: if ((mode&~0x70)!=OF_READ)
|
||||
6: 546: return fd;
|
||||
4: 547: if (fd==HFILE_ERROR)
|
||||
1: 548: return HFILE_ERROR;
|
||||
3: 549: cfd=LZInit(fd);
|
||||
3: 550: if ((INT)cfd <= 0) return fd;
|
||||
3: 551: return cfd;
|
||||
</screen>
|
||||
<para>
|
||||
Based on gcov, we now know that
|
||||
<constant>HFILE_ERROR</constant> is returned once. And since
|
||||
all of our other tests have remain unchanged, we can assume
|
||||
that the one time it is returned is to satisfy the one case we
|
||||
added where we check for it. Thus we have validated a line of
|
||||
code. While this is a cursory example, it demostrates the
|
||||
potential usefulness of this tool.
|
||||
</para>
|
||||
<para>
|
||||
For a further in depth description of gcov, the official gcc
|
||||
compiler suite page for gcov is <ulink
|
||||
url="http://gcc.gnu.org/onlinedocs/gcc-3.2.3/gcc/Gcov.html">
|
||||
http://gcc.gnu.org/onlinedocs/gcc-3.2.3/gcc/Gcov.html</ulink>.
|
||||
There is also an excellent article written by Steve Best for
|
||||
Linux Magazine which describes and illustrates this process
|
||||
very well at
|
||||
<ulink url="http://www.linux-mag.com/2003-07/compile_01.html">
|
||||
http://www.linux-mag.com/2003-07/compile_01.html</ulink>.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
</chapter>
|
||||
|
||||
<!-- Keep this comment at the end of the file
|
||||
Local variables:
|
||||
mode: sgml
|
||||
sgml-parent-document:("wine-devel.sgml" "set" "book" "part" "chapter" "")
|
||||
End:
|
||||
-->
|
|
@ -1,673 +0,0 @@
|
|||
<chapter>
|
||||
<title>Windowing system</title>
|
||||
<sect1>
|
||||
<title>USER Module</title>
|
||||
|
||||
<para>
|
||||
USER implements windowing and messaging subsystems. It also
|
||||
contains code for common controls and for other
|
||||
miscellaneous stuff (rectangles, clipboard, WNet, etc).
|
||||
Wine USER code is located in <filename>windows/</filename>,
|
||||
<filename>controls/</filename>, and
|
||||
<filename>misc/</filename> directories.
|
||||
</para>
|
||||
|
||||
<sect2>
|
||||
<title>Windowing subsystem</title>
|
||||
|
||||
<para><filename>windows/win.c</filename></para>
|
||||
<para><filename>windows/winpos.c</filename></para>
|
||||
<para>
|
||||
Windows are arranged into parent/child hierarchy with one
|
||||
common ancestor for all windows (desktop window). Each
|
||||
window structure contains a pointer to the immediate
|
||||
ancestor (parent window if <constant>WS_CHILD</constant>
|
||||
style bit is set), a pointer to the sibling (returned by
|
||||
<function>GetWindow(..., GW_NEXT)</function>), a pointer
|
||||
to the owner window (set only for popup window if it was
|
||||
created with valid <varname>hwndParent</varname>
|
||||
parameter), and a pointer to the first child window
|
||||
(<function>GetWindow(.., GW_CHILD)</function>). All popup
|
||||
and non-child windows are therefore placed in the first
|
||||
level of this hierarchy and their ancestor link
|
||||
(<varname>wnd->parent</varname>) points to the desktop
|
||||
window.
|
||||
</para>
|
||||
<screen>
|
||||
Desktop window - root window
|
||||
| \ `-.
|
||||
| \ `-.
|
||||
popup -> wnd1 -> wnd2 - top level windows
|
||||
| \ `-. `-.
|
||||
| \ `-. `-.
|
||||
child1 child2 -> child3 child4 - child windows
|
||||
</screen>
|
||||
<para>
|
||||
Horizontal arrows denote sibling relationship, vertical
|
||||
lines - ancestor/child. To summarize, all windows with the
|
||||
same immediate ancestor are sibling windows, all windows
|
||||
which do not have desktop as their immediate ancestor are
|
||||
child windows. Popup windows behave as topmost top-level
|
||||
windows unless they are owned. In this case the only
|
||||
requirement is that they must precede their owners in the
|
||||
top-level sibling list (they are not topmost). Child
|
||||
windows are confined to the client area of their parent
|
||||
windows (client area is where window gets to do its own
|
||||
drawing, non-client area consists of caption, menu,
|
||||
borders, intrinsic scrollbars, and
|
||||
minimize/maximize/close/help buttons).
|
||||
</para>
|
||||
<para>
|
||||
Another fairly important concept is
|
||||
<firstterm>z-order</firstterm>. It is derived from the
|
||||
ancestor/child hierarchy and is used to determine
|
||||
"above/below" relationship. For instance, in the example
|
||||
above, z-order is
|
||||
</para>
|
||||
<screen>
|
||||
child1->popup->child2->child3->wnd1->child4->wnd2->desktop.
|
||||
</screen>
|
||||
<para>
|
||||
Current active window ("foreground window" in Win32) is
|
||||
moved to the front of z-order unless its top-level
|
||||
ancestor owns popup windows.
|
||||
</para>
|
||||
<para>
|
||||
All these issues are dealt with (or supposed to be) in
|
||||
<filename>windows/winpos.c</filename> with
|
||||
<function>SetWindowPos()</function> being the primary
|
||||
interface to the window manager.
|
||||
</para>
|
||||
<para>
|
||||
Wine specifics: in default and managed mode each top-level
|
||||
window gets its own X counterpart with desktop window
|
||||
being basically a fake stub. In desktop mode, however,
|
||||
only desktop window has an X window associated with it.
|
||||
Also, <function>SetWindowPos()</function> should
|
||||
eventually be implemented via
|
||||
<function>Begin/End/DeferWindowPos()</function> calls and
|
||||
not the other way around.
|
||||
</para>
|
||||
|
||||
<sect3>
|
||||
<title>Visible region, clipping region and update region</title>
|
||||
|
||||
<para><filename>windows/dce.c</filename></para>
|
||||
<para><filename>windows/winpos.c</filename></para>
|
||||
<para><filename>windows/painting.c</filename></para>
|
||||
|
||||
<screen>
|
||||
________________________
|
||||
|_________ | A and B are child windows of C
|
||||
| A |______ |
|
||||
| | | |
|
||||
|---------' | |
|
||||
| | B | |
|
||||
| | | |
|
||||
| `------------' |
|
||||
| C |
|
||||
`------------------------'
|
||||
</screen>
|
||||
<para>
|
||||
Visible region determines which part of the window is
|
||||
not obscured by other windows. If a window has the
|
||||
<constant>WS_CLIPCHILDREN</constant> style then all
|
||||
areas below its children are considered invisible.
|
||||
Similarly, if the <constant>WS_CLIPSIBLINGS</constant>
|
||||
bit is in effect then all areas obscured by its siblings
|
||||
are invisible. Child windows are always clipped by the
|
||||
boundaries of their parent windows.
|
||||
</para>
|
||||
<para>
|
||||
B has a <constant>WS_CLIPSIBLINGS</constant> style:
|
||||
</para>
|
||||
<screen>
|
||||
. ______
|
||||
: | |
|
||||
| ,-----' |
|
||||
| | B | - visible region of B
|
||||
| | |
|
||||
: `------------'
|
||||
</screen>
|
||||
<para>
|
||||
When the program requests a <firstterm>display
|
||||
context</firstterm> (DC) for a window it can specify
|
||||
an optional clipping region that further restricts the
|
||||
area where the graphics output can appear. This area is
|
||||
calculated as an intersection of the visible region and
|
||||
a clipping region.
|
||||
</para>
|
||||
<para>
|
||||
Program asked for a DC with a clipping region:
|
||||
</para>
|
||||
<screen>
|
||||
______
|
||||
,--|--. | . ,--.
|
||||
,--+--' | | : _: |
|
||||
| | B | | => | | | - DC region where the painting will
|
||||
| | | | | | | be visible
|
||||
`--|-----|---' : `----'
|
||||
`-----'
|
||||
</screen>
|
||||
<para>
|
||||
When the window manager detects that some part of the window
|
||||
became visible it adds this area to the update region of this
|
||||
window and then generates <constant>WM_ERASEBKGND</constant> and
|
||||
<constant>WM_PAINT</constant> messages. In addition,
|
||||
<constant>WM_NCPAINT</constant> message is sent when the
|
||||
uncovered area intersects a nonclient part of the window.
|
||||
Application must reply to the <constant>WM_PAINT</constant>
|
||||
message by calling the
|
||||
<function>BeginPaint()</function>/<function>EndPaint()</function>
|
||||
pair of functions. <function>BeginPaint()</function> returns a DC
|
||||
that uses accumulated update region as a clipping region. This
|
||||
operation cleans up invalidated area and the window will not
|
||||
receive another <constant>WM_PAINT</constant> until the window
|
||||
manager creates a new update region.
|
||||
</para>
|
||||
<para>
|
||||
A was moved to the left:
|
||||
</para>
|
||||
<screen>
|
||||
________________________ ... / C update region
|
||||
|______ | : .___ /
|
||||
| A |_________ | => | ...|___|..
|
||||
| | | | | : | |
|
||||
|------' | | | : '---'
|
||||
| | B | | | : \
|
||||
| | | | : \
|
||||
| `------------' | B update region
|
||||
| C |
|
||||
`------------------------'
|
||||
</screen>
|
||||
<para>
|
||||
Windows maintains a display context cache consisting of
|
||||
entries that include the DC itself, the window to which
|
||||
it belongs, and an optional clipping region (visible
|
||||
region is stored in the DC itself). When an API call
|
||||
changes the state of the window tree, window manager has
|
||||
to go through the DC cache to recalculate visible
|
||||
regions for entries whose windows were involved in the
|
||||
operation. DC entries (DCE) can be either private to the
|
||||
window, or private to the window class, or shared
|
||||
between all windows (Windows 3.1 limits the number of
|
||||
shared DCEs to 5).
|
||||
</para>
|
||||
</sect3>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Messaging subsystem</title>
|
||||
|
||||
<para><filename>windows/queue.c</filename></para>
|
||||
<para><filename>windows/message.c</filename></para>
|
||||
|
||||
<para>
|
||||
Each Windows task/thread has its own message queue - this
|
||||
is where it gets messages from. Messages can be:
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
generated on the fly (<constant>WM_PAINT</constant>,
|
||||
<constant>WM_NCPAINT</constant>,
|
||||
<constant>WM_TIMER</constant>)
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
created by the system (hardware messages)
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
posted by other tasks/threads (<function>PostMessage</function>)
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
sent by other tasks/threads (<function>SendMessage</function>)
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
</para>
|
||||
<para>
|
||||
Message priority:
|
||||
</para>
|
||||
<para>
|
||||
First the system looks for sent messages, then for posted
|
||||
messages, then for hardware messages, then it checks if
|
||||
the queue has the "dirty window" bit set, and, finally, it
|
||||
checks for expired timers. See
|
||||
<filename>windows/message.c</filename>.
|
||||
</para>
|
||||
<para>
|
||||
From all these different types of messages, only posted
|
||||
messages go directly into the private message queue.
|
||||
System messages (even in Win95) are first collected in the
|
||||
system message queue and then they either sit there until
|
||||
<function>Get/PeekMessage</function> gets to process them
|
||||
or, as in Win95, if system queue is getting clobbered, a
|
||||
special thread ("raw input thread") assigns them to the
|
||||
private queues. Sent messages are queued separately and
|
||||
the sender sleeps until it gets a reply. Special messages
|
||||
are generated on the fly depending on the window/queue
|
||||
state. If the window update region is not empty, the
|
||||
system sets the <constant>QS_PAINT</constant> bit in the
|
||||
owning queue and eventually this window receives a
|
||||
<constant>WM_PAINT</constant> message
|
||||
(<constant>WM_NCPAINT</constant> too if the update region
|
||||
intersects with the non-client area). A timer event is
|
||||
raised when one of the queue timers expire. Depending on
|
||||
the timer parameters <function>DispatchMessage</function>
|
||||
either calls the callback function or the window
|
||||
procedure. If there are no messages pending the
|
||||
task/thread sleeps until messages appear.
|
||||
</para>
|
||||
<para>
|
||||
There are several tricky moments (open for discussion) -
|
||||
</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
System message order has to be honored and messages
|
||||
should be processed within correct task/thread
|
||||
context. Therefore when <function>Get/PeekMessage</function> encounters
|
||||
unassigned system message and this message appears not
|
||||
to be for the current task/thread it should either
|
||||
skip it (or get rid of it by moving it into the
|
||||
private message queue of the target task/thread -
|
||||
Win95, AFAIK) and look further or roll back and then
|
||||
yield until this message gets processed when system
|
||||
switches to the correct context (Win16). In the first
|
||||
case we lose correct message ordering, in the second
|
||||
case we have the infamous synchronous system message
|
||||
queue. Here is a post to one of the OS/2 newsgroup I
|
||||
found to be relevant:
|
||||
</para>
|
||||
<blockquote>
|
||||
<attribution>by David Charlap</attribution>
|
||||
<para>
|
||||
" Here's the problem in a nutshell, and there is no
|
||||
good solution. Every possible solution creates a
|
||||
different problem.
|
||||
</para>
|
||||
<para>
|
||||
With a windowing system, events can go to many
|
||||
different windows. Most are sent by applications or
|
||||
by the OS when things relating to that window happen
|
||||
(like repainting, timers, etc.)
|
||||
</para>
|
||||
<para>
|
||||
Mouse input events go to the window you click on
|
||||
(unless some window captures the mouse).
|
||||
</para>
|
||||
<para>
|
||||
So far, no problem. Whenever an event happens, you
|
||||
put a message on the target window's message queue.
|
||||
Every process has a message queue. If the process
|
||||
queue fills up, the messages back up onto the system
|
||||
queue.
|
||||
</para>
|
||||
<para>
|
||||
This is the first cause of apps hanging the GUI. If
|
||||
an app doesn't handle messages and they back up into
|
||||
the system queue, other apps can't get any more
|
||||
messages. The reason is that the next message in
|
||||
line can't go anywhere, and the system won't skip
|
||||
over it.
|
||||
</para>
|
||||
<para>
|
||||
This can be fixed by making apps have bigger private
|
||||
message queues. The SIQ fix does this. PMQSIZE does
|
||||
this for systems without the SIQ fix. Applications
|
||||
can also request large queues on their own.
|
||||
</para>
|
||||
<para>
|
||||
Another source of the problem, however, happens when
|
||||
you include keyboard events. When you press a key,
|
||||
there's no easy way to know what window the
|
||||
keystroke message should be delivered to.
|
||||
</para>
|
||||
<para>
|
||||
Most windowing systems use a concept known as
|
||||
"focus". The window with focus gets all incoming
|
||||
keyboard messages. Focus can be changed from window
|
||||
to window by apps or by users clicking on windows.
|
||||
</para>
|
||||
<para>
|
||||
This is the second source of the problem. Suppose
|
||||
window A has focus. You click on window B and start
|
||||
typing before the window gets focus. Where should
|
||||
the keystrokes go? On the one hand, they should go
|
||||
to A until the focus actually changes to B. On the
|
||||
other hand, you probably want the keystrokes to go
|
||||
to B, since you clicked there first.
|
||||
</para>
|
||||
<para>
|
||||
OS/2's solution is that when a focus-changing event
|
||||
happens (like clicking on a window), OS/2 holds all
|
||||
messages in the system queue until the focus change
|
||||
actually happens. This way, subsequent keystrokes
|
||||
go to the window you clicked on, even if it takes a
|
||||
while for that window to get focus.
|
||||
</para>
|
||||
<para>
|
||||
The downside is that if the window takes a real long
|
||||
time to get focus (maybe it's not handling events,
|
||||
or maybe the window losing focus isn't handling
|
||||
events), everything backs up in the system queue and
|
||||
the system appears hung.
|
||||
</para>
|
||||
<para>
|
||||
There are a few solutions to this problem.
|
||||
</para>
|
||||
<para>
|
||||
One is to make focus policy asynchronous. That is,
|
||||
focus changing has absolutely nothing to do with the
|
||||
keyboard. If you click on a window and start typing
|
||||
before the focus actually changes, the keystrokes go
|
||||
to the first window until focus changes, then they
|
||||
go to the second. This is what X-windows does.
|
||||
</para>
|
||||
<para>
|
||||
Another is what NT does. When focus changes,
|
||||
keyboard events are held in the system message
|
||||
queue, but other events are allowed through. This is
|
||||
"asynchronous" because the messages in the system
|
||||
queue are delivered to the application queues in a
|
||||
different order from that with which they were
|
||||
posted. If a bad app won't handle the "lose focus"
|
||||
message, it's of no consequence - the app receiving
|
||||
focus will get its "gain focus" message, and the
|
||||
keystrokes will go to it.
|
||||
</para>
|
||||
<para>
|
||||
The NT solution also takes care of the application
|
||||
queue filling up problem. Since the system delivers
|
||||
messages asynchronously, messages waiting in the
|
||||
system queue will just sit there and the rest of the
|
||||
messages will be delivered to their apps.
|
||||
</para>
|
||||
<para>
|
||||
The OS/2 SIQ solution is this: When a
|
||||
focus-changing event happens, in addition to
|
||||
blocking further messages from the application
|
||||
queues, a timer is started. When the timer goes
|
||||
off, if the focus change has not yet happened, the
|
||||
bad app has its focus taken away and all messages
|
||||
targeted at that window are skipped. When the bad
|
||||
app finally handles the focus change message, OS/2
|
||||
will detect this and stop skipping its messages.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
As for the pros and cons:
|
||||
</para>
|
||||
<para>
|
||||
The X-windows solution is probably the easiest. The
|
||||
problem is that users generally don't like having to
|
||||
wait for the focus to change before they start
|
||||
typing. On many occasions, you can type and the
|
||||
characters end up in the wrong window because
|
||||
something (usually heavy system load) is preventing
|
||||
the focus change from happening in a timely manner.
|
||||
</para>
|
||||
<para>
|
||||
The NT solution seems pretty nice, but making the
|
||||
system message queue asynchronous can cause similar
|
||||
problems to the X-windows problem. Since messages
|
||||
can be delivered out of order, programs must not
|
||||
assume that two messages posted in a particular
|
||||
order will be delivered in that same order. This
|
||||
can break legacy apps, but since Win32 always had an
|
||||
asynchronous queue, it is fair to simply tell app
|
||||
designers "don't do that". It's harder to tell app
|
||||
designers something like that on OS/2 - they'll
|
||||
complain "you changed the rules and our apps are
|
||||
breaking."
|
||||
</para>
|
||||
<para>
|
||||
The OS/2 solution's problem is that nothing happens
|
||||
until you try to change window focus, and then wait
|
||||
for the timeout. Until then, the bad app is not
|
||||
detected and nothing is done."
|
||||
</para>
|
||||
</blockquote>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
Intertask/interthread
|
||||
<function>SendMessage</function>. The system has to
|
||||
inform the target queue about the forthcoming message,
|
||||
then it has to carry out the context switch and wait
|
||||
until the result is available. Win16 stores necessary
|
||||
parameters in the queue structure and then calls
|
||||
<function>DirectedYield()</function> function.
|
||||
However, in Win32 there could be several messages
|
||||
pending sent by preemptively executing threads, and in
|
||||
this case <function>SendMessage</function> has to
|
||||
build some sort of message queue for sent messages.
|
||||
Another issue is what to do with messages sent to the
|
||||
sender when it is blocked inside its own
|
||||
<function>SendMessage</function>.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</sect2>
|
||||
<sect2 id="accel-impl">
|
||||
<title>Accelerators</title>
|
||||
|
||||
<para>
|
||||
There are <emphasis>three</emphasis> differently sized
|
||||
accelerator structures exposed to the user:
|
||||
</para>
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
Accelerators in NE resources. This is also the internal
|
||||
layout of the global handle <type>HACCEL</type> (16 and
|
||||
32) in Windows 95 and Wine. Exposed to the user as Win16
|
||||
global handles <type>HACCEL16</type> and
|
||||
<type>HACCEL32</type> by the Win16/Win32 API.
|
||||
These are 5 bytes long, with no padding:
|
||||
<programlisting>
|
||||
BYTE fVirt;
|
||||
WORD key;
|
||||
WORD cmd;
|
||||
</programlisting>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Accelerators in PE resources. They are exposed to the
|
||||
user only by direct accessing PE resources. These have a
|
||||
size of 8 bytes:
|
||||
</para>
|
||||
<programlisting>
|
||||
BYTE fVirt;
|
||||
BYTE pad0;
|
||||
WORD key;
|
||||
WORD cmd;
|
||||
WORD pad1;
|
||||
</programlisting>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Accelerators in the Win32 API. These are exposed to the
|
||||
user by the <function>CopyAcceleratorTable</function>
|
||||
and <function>CreateAcceleratorTable</function> functions
|
||||
in the Win32 API.
|
||||
These have a size of 6 bytes:
|
||||
</para>
|
||||
<programlisting>
|
||||
BYTE fVirt;
|
||||
BYTE pad0;
|
||||
WORD key;
|
||||
WORD cmd;
|
||||
</programlisting>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
|
||||
<para>
|
||||
Why two types of accelerators in the Win32 API? We can only
|
||||
guess, but my best bet is that the Win32 resource compiler
|
||||
can/does not handle struct packing. Win32 <type>ACCEL</type>
|
||||
is defined using <function>#pragma(2)</function> for the
|
||||
compiler but without any packing for RC, so it will assume
|
||||
<function>#pragma(4)</function>.
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
<sect1>
|
||||
<title>X Windows System interface</title>
|
||||
<para></para>
|
||||
<sect2>
|
||||
<title>Keyboard mapping</title>
|
||||
<para>
|
||||
Wine now needs to know about your keyboard layout. This
|
||||
requirement comes from a need from many apps to have the
|
||||
correct scancodes available, since they read these directly,
|
||||
instead of just taking the characters returned by the X
|
||||
server. This means that Wine now needs to have a mapping
|
||||
from X keys to the scancodes these programs expect.
|
||||
</para>
|
||||
<para>
|
||||
On startup, Wine will try to recognize the active X layout
|
||||
by seeing if it matches any of the defined tables. If it
|
||||
does, everything is alright. If not, you need to define it.
|
||||
</para>
|
||||
<para>
|
||||
To do this, open the file
|
||||
<filename>dlls/x11drv/keyboard.c</filename> and take a look
|
||||
at the existing tables. Make a backup copy of it, especially
|
||||
if you don't use CVS.
|
||||
</para>
|
||||
<para>
|
||||
What you really would need to do, is find out which scancode
|
||||
each key needs to generate. Find it in the
|
||||
<function>main_key_scan</function> table, which looks like
|
||||
this:
|
||||
</para>
|
||||
<programlisting>
|
||||
static const int main_key_scan[MAIN_LEN] =
|
||||
{
|
||||
/* this is my (102-key) keyboard layout, sorry if it doesn't quite match yours */
|
||||
0x29,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,
|
||||
0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,
|
||||
0x1E,0x1F,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x2B,
|
||||
0x2C,0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,0x35,
|
||||
0x56 /* the 102nd key (actually to the right of l-shift) */
|
||||
};
|
||||
</programlisting>
|
||||
<para>
|
||||
Next, assign each scancode the characters imprinted on the
|
||||
keycaps. This was done (sort of) for the US 101-key keyboard,
|
||||
which you can find near the top in
|
||||
<filename>keyboard.c</filename>. It also shows that if there
|
||||
is no 102nd key, you can skip that.
|
||||
</para>
|
||||
<para>
|
||||
However, for most international 102-key keyboards, we have
|
||||
done it easy for you. The scancode layout for these already
|
||||
pretty much matches the physical layout in the
|
||||
<function>main_key_scan</function>, so all you need to do is
|
||||
to go through all the keys that generate characters on your
|
||||
main keyboard (except spacebar), and stuff those into an
|
||||
appropriate table. The only exception is that the 102nd key,
|
||||
which is usually to the left of the first key of the last
|
||||
line (usually <keycap>Z</keycap>), must be placed on a
|
||||
separate line after the last line.
|
||||
</para>
|
||||
<para>
|
||||
For example, my Norwegian keyboard looks like this
|
||||
</para>
|
||||
<screen>
|
||||
§ ! " # ¤ % & / ( ) = ? ` Back-
|
||||
| 1 2@ 3£ 4$ 5 6 7{ 8[ 9] 0} + \´ space
|
||||
|
||||
Tab Q W E R T Y U I O P Å ^
|
||||
¨~
|
||||
Enter
|
||||
Caps A S D F G H J K L Ø Æ *
|
||||
Lock '
|
||||
|
||||
Sh- > Z X C V B N M ; : _ Shift
|
||||
ift < , . -
|
||||
|
||||
Ctrl Alt Spacebar AltGr Ctrl
|
||||
</screen>
|
||||
<para>
|
||||
Note the 102nd key, which is the <keycap><></keycap> key, to
|
||||
the left of <keycap>Z</keycap>. The character to the right of
|
||||
the main character is the character generated by
|
||||
<keycap>AltGr</keycap>.
|
||||
</para>
|
||||
<para>
|
||||
This keyboard is defined as follows:
|
||||
</para>
|
||||
<programlisting>
|
||||
static const char main_key_NO[MAIN_LEN][4] =
|
||||
{
|
||||
"|§","1!","2\"@","3#£","4¤$","5%","6&","7/{","8([","9)]","0=}","+?","\\´",
|
||||
"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","åÅ","¨^~",
|
||||
"aA","sS","dD","fF","gG","hH","jJ","kK","lL","øØ","æÆ","'*",
|
||||
"zZ","xX","cC","vV","bB","nN","mM",",;",".:","-_",
|
||||
"<>"
|
||||
};
|
||||
</programlisting>
|
||||
<para>
|
||||
Except that " and \ needs to be quoted with a backslash, and
|
||||
that the 102nd key is on a separate line, it's pretty
|
||||
straightforward.
|
||||
</para>
|
||||
<para>
|
||||
After you have written such a table, you need to add it to the
|
||||
<function>main_key_tab[]</function> layout index table. This
|
||||
will look like this:
|
||||
</para>
|
||||
<programlisting>
|
||||
static struct {
|
||||
WORD lang, ansi_codepage, oem_codepage;
|
||||
const char (*key)[MAIN_LEN][4];
|
||||
} main_key_tab[]={
|
||||
...
|
||||
...
|
||||
{MAKELANGID(LANG_NORWEGIAN,SUBLANG_DEFAULT), 1252, 865, &main_key_NO},
|
||||
...
|
||||
</programlisting>
|
||||
<para>
|
||||
After you have added your table, recompile Wine and test that
|
||||
it works. If it fails to detect your table, try running
|
||||
</para>
|
||||
<screen>
|
||||
WINEDEBUG=+key,+keyboard wine > key.log 2>&1
|
||||
</screen>
|
||||
<para>
|
||||
and look in the resulting <filename>key.log</filename> file to
|
||||
find the error messages it gives for your layout.
|
||||
</para>
|
||||
<para>
|
||||
Note that the <constant>LANG_*</constant> and
|
||||
<constant>SUBLANG_*</constant> definitions are in
|
||||
<filename>include/winnls.h</filename>, which you might need
|
||||
to know to find out which numbers your language is assigned,
|
||||
and find it in the WINEDEBUG output. The numbers will be
|
||||
<literal>(SUBLANG * 0x400 + LANG)</literal>, so, for example
|
||||
the combination <literal>LANG_NORWEGIAN (0x14)</literal> and
|
||||
<literal>SUBLANG_DEFAULT (0x1)</literal> will be (in hex)
|
||||
<literal>14 + 1*400 = 414</literal>, so since I'm Norwegian,
|
||||
I could look for <literal>0414</literal> in the WINEDEBUG
|
||||
output to find out why my keyboard won't detect.
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
||||
<!-- Keep this comment at the end of the file
|
||||
Local variables:
|
||||
mode: sgml
|
||||
sgml-parent-document:("wine-devel.sgml" "set" "book" "part" "chapter" "")
|
||||
End:
|
||||
-->
|
|
@ -1,292 +0,0 @@
|
|||
<chapter id="bindlls">
|
||||
<!-- FIXME: note that you can link PE DLLs to Winelib apps -->
|
||||
<title id="bindlls.title">Building WineLib DLLs</title>
|
||||
<sect1 id="bindlls-intro">
|
||||
<title id="binary-dlls-intro.title">Introduction</title>
|
||||
<para>
|
||||
For one reason or another you may find yourself with a Linux
|
||||
library that you want to use as if it were a Windows Dll. There are
|
||||
various reasons for this including the following:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
You are porting a large application that uses several third-party
|
||||
libraries. One is available on Linux but you are not yet ready
|
||||
to link to it directly as a Linux shared library.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
There is a well-defined interface available and there are several
|
||||
Linux solutions that are available for it
|
||||
(e.g. the ODBC interface in Wine).
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
You have a binary only Windows application that can be extended
|
||||
through plugins, such as a text editor or IDE.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
<para>
|
||||
The process for dealing with these situations is actually quite simple.
|
||||
You need to write a spec file that will describe the library's
|
||||
interface in the same format as a Dll (primarily what functions it
|
||||
exports). Also you will want to write a small wrapper around the
|
||||
library. You combine these to form a Wine built-in Dll that links to the
|
||||
Linux library. Then you modify the DllOverrides in the wine config
|
||||
file to ensure that this new built-in DLL is called rather than any
|
||||
windows version.
|
||||
</para>
|
||||
<para>
|
||||
In this section we will look at two examples. The first example is
|
||||
extremely simple and leads into the subject in "baby steps". The
|
||||
second example is the ODBC interface proxy in Wine. The files to which
|
||||
we will refer for the ODBC example are currently in the
|
||||
<filename class="Directory">dlls/odbc32</filename> directory of the
|
||||
Wine source.
|
||||
</para>
|
||||
<para>
|
||||
The first example is based very closely on a real case (the names
|
||||
of the functions etc. have been changed to protect the innocent).
|
||||
A large Windows application includes a DLL that links to a third-party
|
||||
DLL. For various reasons the third-party DLL does not work too well
|
||||
under Wine. However the third-party library is also available for the
|
||||
Linux environment. Conveniently the DLL and Linux shared library
|
||||
export only a small number of functions and the application only uses
|
||||
one of those.
|
||||
</para>
|
||||
<para>
|
||||
Specifically, the application calls a function:
|
||||
<programlisting>
|
||||
signed short WINAPI MyWinFunc (unsigned short a, void *b, void *c,
|
||||
unsigned long *d, void *e, int f, char g, unsigned char *h);
|
||||
</programlisting>
|
||||
and the linux library exports a corresponding function:
|
||||
<programlisting>
|
||||
signed short MyLinuxFunc (unsigned short a, void *b, void *c,
|
||||
unsigned short *d, void *e, char g, unsigned char *h);
|
||||
</programlisting>
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="bindlls-spec">
|
||||
<title id="bindlls-spec.title">Writing the spec file</title>
|
||||
<para>
|
||||
Start by writing the spec file. This file will describe the interface
|
||||
as if it were a DLL. See elsewhere for the details of the format of
|
||||
a spec file (e.g. man winebuild).
|
||||
</para>
|
||||
<para>
|
||||
In the simple example we want a Wine built-in Dll that corresponds to
|
||||
the MyWin Dll. The spec file is <filename>MyWin.dll.spec</filename> and
|
||||
looks something like this:
|
||||
<programlisting>
|
||||
#
|
||||
# File: MyWin.dll.spec
|
||||
#
|
||||
# some sort of copyright
|
||||
#
|
||||
# Wine spec file for the MyWin.dll built-in library (a minimal wrapper around the
|
||||
# linux library libMyLinux)
|
||||
#
|
||||
# For further details of wine spec files see the Winelib documentation at
|
||||
# www.winehq.org
|
||||
|
||||
2 stdcall MyWinFunc (long ptr ptr ptr ptr long long ptr) MyProxyWinFunc
|
||||
|
||||
# End of file
|
||||
</programlisting>
|
||||
Notice that the arguments are flagged as long even though they are
|
||||
smaller than that. With this example we will link directly to the
|
||||
Linux shared library whereas with the ODBC example we will load the
|
||||
Linux shared library dynamically.
|
||||
</para>
|
||||
<para>
|
||||
In the case of the ODBC example you can see this in the file
|
||||
<filename>odbc32.spec</filename>.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="bindlls-wrapper">
|
||||
<title id="bindlls-wrapper.title">Writing the wrapper</title>
|
||||
<para>
|
||||
Firstly we will look at the simple example. The main complication of
|
||||
this case is the slightly different argument lists. The f parameter
|
||||
does not have to be passed to the Linux function and the d parameter
|
||||
(theoretically) has to be converted between
|
||||
<literal>unsigned long *i</literal> and <literal>unsigned short *</literal>.
|
||||
Doing this ensures that the "high" bits of the returned value are set
|
||||
correctly. Also unlike with the ODBC example we will link directly to
|
||||
the Linux Shared Library.
|
||||
<programlisting>
|
||||
/*
|
||||
* File: MyWin.c
|
||||
*
|
||||
* Copyright (c) The copyright holder.
|
||||
*
|
||||
* Basic Wine wrapper for the Linux <3rd party library> so that it can be
|
||||
* used by <the application>
|
||||
*
|
||||
* Currently this file makes no attempt to be a full wrapper for the <3rd
|
||||
* party library>; it only exports enough for our own use.
|
||||
*
|
||||
* Note that this is a Unix file; please don't go converting it to DOS format
|
||||
* (e.g. converting line feeds to Carriage return/Line feed).
|
||||
*
|
||||
* This file should be built in a Wine environment as a WineLib library,
|
||||
* linked to the Linux <3rd party> libraries (currently libxxxx.so and
|
||||
* libyyyy.so)
|
||||
*/
|
||||
|
||||
#include < <3rd party linux header> >
|
||||
#include <windef.h> /* Part of the Wine header files */
|
||||
|
||||
/* This declaration is as defined in the spec file. It is deliberately not
|
||||
* specified in terms of <3rd party> types since we are messing about here
|
||||
* between two operating systems (making it look like a Windows thing when
|
||||
* actually it is a Linux thing). In this way the compiler will point out any
|
||||
* inconsistencies.
|
||||
* For example the fourth argument needs care
|
||||
*/
|
||||
signed short WINAPI MyProxyWinFunc (unsigned short a, void *b, void *c,
|
||||
unsigned long *d, void *e, int f, char g, unsigned char *h)
|
||||
{
|
||||
unsigned short d1;
|
||||
signed short ret;
|
||||
|
||||
d1 = (unsigned short) *d;
|
||||
ret = <3rd party linux function> (a, b, c, &d1, e, g, h);
|
||||
*d = d1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* End of file */
|
||||
</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
For a more extensive case we can use the ODBC example. This is
|
||||
implemented as a header file
|
||||
(<filename class="HeaderFile">proxyodbc.h</filename>) and the actual
|
||||
C source file (<filename>proxyodbc.c</filename>). Although the file
|
||||
is quite long it is extremely simple in structure.
|
||||
</para>
|
||||
<para>
|
||||
<function>DllMain</function> the function is used to initialize the DLL.
|
||||
On the process attach event the function dynamically links to the
|
||||
desired Linux ODBC library (since there are several available) and
|
||||
builds a list of function pointers. It unlinks on the process
|
||||
detach event.
|
||||
</para>
|
||||
<para>
|
||||
Then each of the functions simply calls the appropriate Linux function
|
||||
through the function pointer that was set up during initialization.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="bindlls-building">
|
||||
<title id="binary-dlls-building.title">Building</title>
|
||||
<para>
|
||||
So how do we actually build the Wine built-in Dll? The easiest way is
|
||||
to get Winemaker to do the hard work for us. For the simple example we
|
||||
have two source files (the wrapper and the spec file). We also have
|
||||
the 3rd party header and library files of course.
|
||||
</para>
|
||||
<para>
|
||||
Put the two source files in a suitable directory and then use
|
||||
winemaker to create the build framework, including configure script,
|
||||
makefile etc. You will want to use the following options of
|
||||
winemaker:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
--nosource-fix and --nogenerate-specs (requires winemaker version
|
||||
0.5.8 or later) to ensure that the two files are not modified.
|
||||
(If using an older version of winemaker then make the two files
|
||||
readonly and ignore the complaints about being unable to modify
|
||||
them).
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
--dll --single-target MyWin --nomfc to specify the target
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
-DMightNeedSomething -I3rd_party_include -L3rd_party_lib -lxxxx
|
||||
-lyyyy where these are the locations of the header files etc.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
<para>
|
||||
After running winemaker I like to edit the Makefile to add the line
|
||||
CEXTRA = -Wall just before the DEFINES =.
|
||||
</para>
|
||||
<para>
|
||||
Then simply run the configure and make as normal (described elsewhere).
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="bindlls-installing">
|
||||
<title id="binary-dlls-installing.title">Installing</title>
|
||||
<para>
|
||||
So how do you install the proxy and ensure that everything connects up
|
||||
correctly? You have quite a bit of flexibility in this area so what
|
||||
follows are not the only options available.
|
||||
</para>
|
||||
<para>
|
||||
Ensure that the actual Linux Shared Object is placed somewhere where
|
||||
the Linux system will be able to find it. Typically this means it
|
||||
should be in one of the directories mentioned in the /etc/ld.so.conf
|
||||
file or somewhere in the path specified by LD_LIBRARY_PATH. If you
|
||||
can link to it from a Linux program it should be OK.
|
||||
</para>
|
||||
<para>
|
||||
Put the proxy shared object (MyWin.dll.so) in the same place as the
|
||||
rest of the built-in DLLs. (If you used winemaker to set up your build
|
||||
environment then running "make install" as root should do that for you)
|
||||
Alternatively ensure that WINEDLLPATH includes the directory containing
|
||||
the proxy shared object.
|
||||
</para>
|
||||
<para>
|
||||
If you have both a Windows DLL and a Linux DLL/proxy pair then you will
|
||||
have to ensure that the correct one gets called. The easiest way is
|
||||
probably simply to rename the windows version so that it doesn't get
|
||||
detected. Alternatively you could specify in the DllOverrides section
|
||||
(or the AppDefaults\\myprog.exe\\DllOverrides section) of the config
|
||||
file (in your .wine directory) that the built-in version be used. Note
|
||||
that if the Windows version Dll is present and is in the same
|
||||
directory as the executable (as opposed to being in the Windows
|
||||
directory) then you will currently need to specify the whole path to
|
||||
the dll, not merely its name.
|
||||
</para>
|
||||
<para>
|
||||
Once you have done this you should be using the Linux Shared Object
|
||||
successfully. If you have problems then set the WINEDEBUG=+module
|
||||
environment variable before running wine to see what is actually happening.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="bindlls-filenames">
|
||||
<title id="binary-dlls-filenames.title">Converting filenames</title>
|
||||
<para>
|
||||
Suppose you want to convert incoming DOS format filenames to their
|
||||
Unix equivalent. Of course there is no suitable function in the true
|
||||
Microsoft Windows API, but wine provides a function for just this
|
||||
task and exports it from its copy of the kernel32 DLL. The function
|
||||
is <function>wine_get_unix_file_name</function> (defined in winbase.h).
|
||||
</para>
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
||||
<!-- Keep this comment at the end of the file
|
||||
Local variables:
|
||||
mode: sgml
|
||||
sgml-parent-document:("winelib-user.sgml" "book" "chapter" "")
|
||||
End:
|
||||
-->
|
|
@ -1,441 +0,0 @@
|
|||
<chapter id="winelib-introduction">
|
||||
<title id="introduction.title">Winelib Introduction</title>
|
||||
|
||||
<sect1 id="winelib-whatis">
|
||||
<title>What is Winelib?</title>
|
||||
|
||||
<para>
|
||||
Winelib is a development toolkit which allows you to compile your
|
||||
Windows applications on Unix.
|
||||
</para>
|
||||
<para>
|
||||
Most of Winelib's code consists of the Win32 API implementation.
|
||||
Fortunately this part is 100 percent shared with Wine. The remainder
|
||||
consists of Windows compatible headers and tools like the resource
|
||||
compiler (and even these are used when compiling Wine).
|
||||
</para>
|
||||
<para>
|
||||
Thanks to the above, Winelib supports most C and C++ 32bit source code,
|
||||
resource and message files, and can generate graphical or console
|
||||
applications as well as dynamic libraries.
|
||||
</para>
|
||||
<para>
|
||||
What is not supported is 16bit source code as the types it depends on
|
||||
(especially segmented pointers) are not supported by Unix compilers.
|
||||
Also missing are some of the more exotic features of Microsoft's
|
||||
compiler like native COM support and structured exception handling.
|
||||
So you may need to perform some modifications in your code when
|
||||
recompiling your application with Winelib. This guide is here to help
|
||||
you in this task.
|
||||
</para>
|
||||
<para>
|
||||
What you gain by recompiling your application with Winelib is the
|
||||
ability to make calls to Unix APIs, directly from your
|
||||
Windows source code. This allows for a better integration with the
|
||||
Unix environment than is allowed by running an unmodified Windows
|
||||
application running in Wine. Another benefit is that a Winelib
|
||||
application can relatively easily be recompiled on a non-Intel
|
||||
architecture and run there without the need for a slow software
|
||||
emulation of the processor.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="winelib-requirements">
|
||||
<title id="requirements.title">System requirements</title>
|
||||
<para>
|
||||
The requirements for Winelib are similar to those for Wine.
|
||||
</para>
|
||||
<para>
|
||||
Basically if you can run Wine on your computer then you can run
|
||||
Winelib. But the converse is not true. You can also build Winelib
|
||||
and Winelib applications on platforms not supported by Wine,
|
||||
typically platforms with a non i386 processor. But this is still
|
||||
pretty much uncharted territory. It would be more reasonable to
|
||||
target one of the more mundane i386-based platforms first.
|
||||
</para>
|
||||
<para>
|
||||
The main difference is that the compiler becomes much more important.
|
||||
It is highly recommended that you use gcc, g++, and the GNU binutils.
|
||||
The more recent your gcc compiler the better.
|
||||
For any serious amount of code you should not consider anything older
|
||||
than gcc 2.95.2. The latest gcc snapshots contain some useful bug
|
||||
fixes and much better support for anonymous structs and unions. This
|
||||
can help reduce the number of changes you have to do in your code but
|
||||
these are not stable releases of the compiler so you may not want to
|
||||
use them in production.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="winelib-getting-started">
|
||||
<title id="getting-started.title">Getting Started</title>
|
||||
|
||||
<sect2 id="winemaker-introduction">
|
||||
<title id="winemaker-introduction.title">Winemaker introduction</title>
|
||||
<para>
|
||||
So what is needed to compile a Windows application with Winelib?
|
||||
Well, it really depends on the complexity of your application but
|
||||
here are some issues that are shared by all applications:
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
the case of your files may be bad. For example they could be
|
||||
in all caps: <filename>HELLO.C</filename>. It's not very nice to
|
||||
work with and probably not what you intended.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
then the case of the filenames in your include statements may be
|
||||
wrong: maybe they include <filename>Windows.h</filename> instead
|
||||
of <filename>windows.h</filename>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
your include statements may use '\' instead of '/'. '\' is not
|
||||
recognized by Unix compilers while '/' is recognized in both
|
||||
environments.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
you will need to perform the usual Dos to Unix text file conversion
|
||||
otherwise you'll get in trouble when the compiler considers that
|
||||
your '\' is not at the end of the line since it is followed by a
|
||||
pesky carriage return.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
you will have to write new makefiles.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>
|
||||
The best way to take care of all these issues is to use winemaker.
|
||||
</para>
|
||||
<para>
|
||||
Winemaker is a perl script which is designed to help you bootstrap
|
||||
the conversion of your Windows projects to Winelib. In order to do
|
||||
this it will go analyze your code, fixing the issues listed above
|
||||
and generate straight Makefiles.
|
||||
</para>
|
||||
<para>
|
||||
Let's suppose that you are already in the top directory of your
|
||||
sources. Then converting your project to Winelib may be as simple
|
||||
as just running the three commands below (note the dot indicating
|
||||
current directory at the end of the first command):
|
||||
</para>
|
||||
<programlisting>
|
||||
$ winemaker --lower-uppercase .
|
||||
$ make
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
But of course things are not always that simple which is why we have
|
||||
this guide at all.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="winemaker-test">
|
||||
<title id="winemaker-test.title">Test Drive</title>
|
||||
|
||||
<para>
|
||||
Before starting to work on a big project you may want to try to port a
|
||||
small application. The notepad application from the Wine source tree
|
||||
suits well for testing purposes. It can be found in the programs
|
||||
subdirectory. notepad is a simple application, but has a few C,
|
||||
header and resource files.
|
||||
</para>
|
||||
<para>
|
||||
Run <command>make clean</command> in the
|
||||
notepad source directory if it contains results of previous builds.
|
||||
Create a separate directory with name notepad2, so it won't conflict
|
||||
with the Wine copy of the application. Copy the sources of notepad
|
||||
(files *.c, *.h, *.rc) to this directory. Now run the commands,
|
||||
mentioned above from the notepad2 directory:
|
||||
</para>
|
||||
<programlisting>
|
||||
$ winemaker --lower-uppercase .
|
||||
$ make
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
Notice how the build fails in a resource file
|
||||
(<filename>Da.rc</filename> at the time this was written).
|
||||
This is because for the time being, the Wine resource compiler
|
||||
(<command>windres</command>) can't cope with more than one
|
||||
resource file ending up in a given executable. To get around
|
||||
that limitation, the Wine developers have chosen to only have
|
||||
one master resource file per application, and include the
|
||||
other ones via <literal>#include</literal> statements in the
|
||||
master one. The included files do not
|
||||
<literal>#include</literal> the necessary files to be
|
||||
compilable on their own. You will need to do the same thing
|
||||
for now in your own Winelib port projects.
|
||||
</para>
|
||||
<para>
|
||||
To fix that problem, you will need to edit the list of
|
||||
resource files winemaker thought notepad used, and only keep
|
||||
the master resource file. To do so, open
|
||||
<filename>notepad2/Makefile</filename> in a text editor and
|
||||
search for an assignment to a variable with
|
||||
<literal>RC_SRCS</literal> as part of its name. It will likely
|
||||
be named <literal>notepad2_exe_RC_SRCS</literal>. There will
|
||||
be a list of resource files starting on the same line. Remove
|
||||
them all except <filename>rsrc.rc</filename> (this is the
|
||||
master one for notepad). Save your work.
|
||||
</para>
|
||||
<para>
|
||||
Now you're ready to continue at the same point the first
|
||||
<command>make</command> failed. Return to the notepad2
|
||||
directory and type:
|
||||
</para>
|
||||
<programlisting>
|
||||
$ make
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
You are done! Now you can start the application as
|
||||
<command>./notepad2</command>.
|
||||
</para>
|
||||
<para>
|
||||
If you come across problems preparing and building this application
|
||||
this probably means that winemaker utility is broken by some changes
|
||||
in Wine. Try asking for help on <email>wine-devel@winehq.org</email>
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="winemaker-guide">
|
||||
<title id="winemaker-guide.title">Step by step guide</title>
|
||||
|
||||
<para>
|
||||
Let's retrace the steps above in more details.
|
||||
</para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><option>Getting the source</option></term>
|
||||
<listitem>
|
||||
<para>
|
||||
First if you can try to get the sources together with the
|
||||
executables/libraries that they build. In the current state of
|
||||
winemaker having these around can help it guess what it is that
|
||||
your project is trying to build. Later, when it is able to
|
||||
understand Visual C++ projects, and if you use them, this will
|
||||
no longer be necessary. Usually the executables and libraries
|
||||
are in a <filename class="Directory">Release</filename> or
|
||||
<filename class="Directory">Debug</filename> subdirectory of the
|
||||
directory where the sources are. So it's best if you can
|
||||
transfer the source files and either of these directories to
|
||||
Linux. Note that you don't need to transfer the
|
||||
<filename>.obj</filename>, <filename>.pch</filename>,
|
||||
<filename>.sbr</filename> and other files that also reside in
|
||||
these directories; especially as they tend to be quite big.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>cd <root_dir></option></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Then go to the root directory where are your source files.
|
||||
Winemaker can deal with a whole directory hierarchy at once so
|
||||
you don't need to go into a leaf directory, quite the contrary.
|
||||
Winemaker will automatically generate makefiles in each
|
||||
directory where one is required, and will generate a global
|
||||
makefile so that you can rebuild all your executables and
|
||||
libraries with a single <command>make</command> command.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>Making the source writable</option></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Then make sure you have write access to your sources. It may
|
||||
sound obvious, but if you copied your source files from a
|
||||
CD-ROM or if they are in Source Safe on Windows, chances are
|
||||
that they will be read-only.
|
||||
But Winemaker needs write access so that it can fix them. You
|
||||
can arrange that by running <command>chmod -R u+w .</command>.
|
||||
Also you will want to make sure that you have a backup copy of
|
||||
your sources in case something went horribly wrong, or more
|
||||
likely, just for reference at a later point. If you use a
|
||||
version control system you're already covered.
|
||||
</para>
|
||||
<para>
|
||||
If you have already modified your source files and you want
|
||||
to make sure that winemaker will not make further changes to
|
||||
them then you can use the --nosource-fix option to protect
|
||||
them.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>Running winemaker</option></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Then you'll run winemaker. Here are the options you will most
|
||||
likely want to use. For complete list of options see
|
||||
the winemaker man page.
|
||||
</para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><option>--lower-uppercase</option></term>
|
||||
<term><option>--lower-all</option></term>
|
||||
<listitem>
|
||||
<para>
|
||||
These options specify how to deal with files, and
|
||||
directories, that have an 'incorrect' case.
|
||||
<option>--lower-uppercase</option> specifies they should
|
||||
only be renamed if their name is all uppercase. So files
|
||||
that have a mixed case, like 'Hello.c' would not be
|
||||
renamed. <option>--lower-all</option> will rename any
|
||||
file. If neither is specified then no file or directory
|
||||
will be renamed, almost. As you will see
|
||||
<link linkend="renaming">later</link> winemaker may
|
||||
still have to rename some files.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>--nobackup</option></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Winemaker normally makes a backup of all the files in which
|
||||
it does more than the standard Dos to Unix conversion.
|
||||
But if you already have (handy) copies of these files
|
||||
elsewhere you may not need these so you should use this
|
||||
option.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>--dll</option></term>
|
||||
<term><option>--console</option></term>
|
||||
<listitem>
|
||||
<para>
|
||||
These option lets winemaker know what kind of target you are
|
||||
building. If you have the windows library in your source
|
||||
hierarchy then you should not need to specify
|
||||
<option>--dll</option>. But if you have console executables
|
||||
then you will need to use the corresponding option.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>--mfc</option></term>
|
||||
<listitem>
|
||||
<para>
|
||||
This option tells winemaker that you are building an MFC
|
||||
application/library.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>-Dmacro[=defn]</option></term>
|
||||
<term><option>-Idir</option></term>
|
||||
<term><option>-Ldir</option></term>
|
||||
<term><option>-idll</option></term>
|
||||
<term><option>-llibrary</option></term>
|
||||
<listitem>
|
||||
<para>
|
||||
The <option>-i</option> specifies a Winelib library to
|
||||
import via the <link linkend="spec-file">spec file</>
|
||||
mechanism. Contrast this with the <option>-l</option>
|
||||
which specifies a Unix library to link with. The other
|
||||
options work the same way they would with a C
|
||||
compiler. All are applied to all the targets found.
|
||||
When specifying a directory with either
|
||||
<option>-I</option> or <option>-L</option>, winemaker
|
||||
will prefix a relative path with
|
||||
<literal>$(TOPDIRECTORY)/</literal> so that it is valid
|
||||
from any of the source directories. You can also use a
|
||||
variable in the path yourself if you wish (but don't
|
||||
forget to escape the '$'). For instance you could specify
|
||||
<literal>-I\$(WINELIB_INCLUDE_ROOT)/msvcrt</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
<para>
|
||||
So your command may finally look like:
|
||||
<literal>winemaker --lower-uppercase -Imylib/include .</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term id="renaming"><option>File renaming</option></term>
|
||||
<listitem>
|
||||
<para>
|
||||
When you execute winemaker it will first rename files to bring
|
||||
their character case in line with your expectations and so that they can
|
||||
be processed by the makefiles. This later category implies that
|
||||
files with a non lowercase extension will be renamed so that the
|
||||
extension is in lowercase. So, for instance,
|
||||
<filename>HELLO.C</filename> will be renamed to
|
||||
<filename>HELLO.c</filename>. Also if a file or directory name
|
||||
contains a space or a dollar, then this
|
||||
character will be replaced with an underscore. This is because
|
||||
these characters cause problems with current versions of autoconf
|
||||
(2.13) and make (3.79).
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>Source modifications and makefile generation</option></term>
|
||||
<listitem>
|
||||
<para>
|
||||
winemaker will then proceed to modify the source files so that
|
||||
they will compile more readily with Winelib. As it does so it
|
||||
may print warnings when it has to make a guess or identifies a
|
||||
construct that it cannot correct. Finally it will generate the
|
||||
autoconf-based makefiles. Once all this is done you can review
|
||||
the changes that winemaker did to your files by using
|
||||
<command>diff -uw</command>. For instance:
|
||||
<command>diff -uw hello.c.bak hello.c</command>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>Running make</option></term>
|
||||
<listitem>
|
||||
<para>
|
||||
This is a pretty simple step: just type <command>make</command>
|
||||
and voila, you should have all your executables and libraries.
|
||||
If this did not work out, then it means that you will have to
|
||||
read this guide further to:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
review the <filename>Makefile</filename> files to
|
||||
adjust what winemaker thinks are the binaries you are
|
||||
trying to build and which sources should be used for
|
||||
each. See the <xref linkend="source-analysis"
|
||||
endterm="source-analysis.title"> section for some hints.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
fix the portability issues in your sources. See
|
||||
<xref linkend="portability-issues"
|
||||
endterm="portability-issues.title"> for more details.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</sect2>
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
||||
<!-- Keep this comment at the end of the file
|
||||
Local variables:
|
||||
mode: sgml
|
||||
sgml-parent-document:("winelib-user.sgml" "book" "chapter" "")
|
||||
End:
|
||||
-->
|
|
@ -1,219 +0,0 @@
|
|||
<chapter id="mfc">
|
||||
<title id="mfc.title">Dealing with the MFC</title>
|
||||
|
||||
<sect1 id="mfc-introduction">
|
||||
<title id="mfc-introduction.title">Introduction</title>
|
||||
<para>
|
||||
To use the MFC in a Winelib application you will first have to
|
||||
recompile the MFC with Winelib. In theory it should be possible to
|
||||
write a wrapper for the Windows MFC as described in
|
||||
<xref linkend="bindlls" endterm="bindlls.title">. But in practice
|
||||
it does not seem to be a realistic approach for the MFC:
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
the huge number of APIs makes writing the wrapper a big task in
|
||||
itself.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
furthermore the MFC contain a huge number of APIs which are tricky
|
||||
to deal with when making a wrapper.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
even once you have written the wrapper you will need to modify
|
||||
the MFC headers so that the compiler does not choke on them.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
a big part of the MFC code is actually in your application in
|
||||
the form of macros. This means even more of the MFC headers have
|
||||
to actually work to in order for you to be able to compile an
|
||||
MFC based application.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<para>
|
||||
This is why this guide includes a section dedicated to helping you
|
||||
compile the MFC with Winelib.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="mfc-legal-issues">
|
||||
<title id="mfc-legal-issues.title">Legal issues</title>
|
||||
<para>
|
||||
The purpose of this section is to make you aware of potential legal
|
||||
problems. Be sure to read your licenses and to consult your lawyers.
|
||||
In any case you should not consider the remainder of this section to
|
||||
be authoritative since it has not been written by a lawyer.
|
||||
</para>
|
||||
<para>
|
||||
During the compilation of your program, you will be combining code
|
||||
from several sources: your code, Winelib code, Microsoft MFC code,
|
||||
and possibly code from other vendor sources. As a result, you must
|
||||
ensure that the licenses of all code sources are obeyed. What you are
|
||||
allowed and not allowed to do can vary depending on how you combine
|
||||
the code and if you will be distributing it. For example, if you
|
||||
are releasing your code under the GPL or LGPL, you cannot use MFC
|
||||
because these licenses do not allow covered code to depend on
|
||||
libraries with non-compatible licenses.
|
||||
There is a workaround - in the license for your
|
||||
code you can make an exception for the MFC library.
|
||||
For details see
|
||||
<ulink url="http://www.gnu.org/licenses/gpl-faq.html">The GNU GPL FAQ</ulink>.
|
||||
</para>
|
||||
<para>
|
||||
Wine/Winelib is distributed under the GNU Lesser General Public
|
||||
License. See the license for restrictions on the modification and
|
||||
distribution of Wine/Winelib code. In general it is possible to
|
||||
satisfy these restrictions in any type of application.
|
||||
On the other hand, MFC
|
||||
is distributed under a very restrictive license and the restrictions
|
||||
vary from version to version and between service packs. There are
|
||||
basically three aspects you must be aware of when using the MFC.
|
||||
</para>
|
||||
<para>
|
||||
First you must legally get MFC source code on your computer. The MFC
|
||||
source code comes as a part of Visual Studio. The license for
|
||||
Visual Studio implies it is a single product that cannot
|
||||
be broken up into its components. So the cleanest way to get MFC on
|
||||
your system is to buy Visual Studio and install it on a dual boot
|
||||
Linux box.
|
||||
</para>
|
||||
<para>
|
||||
Then you must check that you are allowed to recompile MFC on a
|
||||
non-Microsoft operating system! This varies with the version of MFC.
|
||||
The MFC license from Visual Studio 6.0 reads in part:
|
||||
</para>
|
||||
<blockquote>
|
||||
<para>
|
||||
1.1 General License Grant. Microsoft grants to you as an
|
||||
individual, a personal, nonexclusive license to make and use
|
||||
copies of the SOFTWARE PRODUCT for the sole purposes of designing,
|
||||
developing, and testing your software product(s) that are designed
|
||||
to operate in conjunction with any Microsoft operating system
|
||||
product. [Other unrelated stuff deleted.]
|
||||
</para>
|
||||
</blockquote>
|
||||
<para>
|
||||
So it appears you cannot even compile MFC for Winelib using this
|
||||
license. Fortunately the Visual Studio 6.0 service pack 3 license
|
||||
reads (the Visual Studio 5.0 license is similar):
|
||||
</para>
|
||||
<blockquote>
|
||||
<para>
|
||||
1.1 General License Grant. Microsoft grants to you as an
|
||||
individual, a personal, nonexclusive license to make and use
|
||||
copies of the SOFTWARE PRODUCT for the purpose of designing,
|
||||
developing, and testing your software product(s). [Other unrelated
|
||||
stuff deleted]
|
||||
</para>
|
||||
</blockquote>
|
||||
<para>
|
||||
So under this license it appears you can compile MFC for Winelib.
|
||||
</para>
|
||||
<para>
|
||||
Finally you must check whether you have the right to distribute an
|
||||
MFC library. Check the relevant section of the license on
|
||||
<quote>redistributables and your redistribution rights</quote>. The
|
||||
license seems to specify that you only have the right to distribute
|
||||
binaries of the MFC library if it has no debug information and if
|
||||
you distribute it with an application that provides significant
|
||||
added functionality to the MFC library.
|
||||
<!-- FIXME: quote relevant sections of EULA in above paragraph. -->
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="mfc-compiling">
|
||||
<title id="mfc-compiling.title">Compiling the MFC</title>
|
||||
<para>
|
||||
Here is a set of recommendations for getting the MFC compiled with
|
||||
WineLib:
|
||||
</para>
|
||||
<para>
|
||||
We recommend running winemaker in
|
||||
'<option>--interactive</option>' mode to specify the right
|
||||
options for the MFC and the ATL part (to get the include paths
|
||||
right, to not consider the MFC MFC-based, and to get it to
|
||||
build libraries, not executables).
|
||||
</para>
|
||||
<para>
|
||||
Then when compiling it you will indeed need a number of
|
||||
<literal>_AFX_NO_XXX</literal> macros. But this is not enough
|
||||
and there are other things you will need to
|
||||
'<literal>#ifdef</literal>-out'. For instance Wine's richedit
|
||||
support is not very good. Here are the AFX options I use:
|
||||
</para>
|
||||
<para>
|
||||
<programlisting>
|
||||
#define _AFX_PORTABLE
|
||||
#define _FORCENAMELESSUNION
|
||||
#define _AFX_NO_DAO_SUPPORT
|
||||
#define _AFX_NO_DHTML_SUPPORT
|
||||
#define _AFX_NO_OLEDB_SUPPORT
|
||||
#define _AFX_NO_RICHEDIT_SUPPORT
|
||||
</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
You will also need custom ones for
|
||||
<function>CMonikerFile</function>, <function>OleDB</function>,
|
||||
<function>HtmlView</function>, ...
|
||||
</para>
|
||||
<para>
|
||||
We recommend using Wine's msvcrt headers (<literal>-isystem
|
||||
$(WINE_INCLUDE_ROOT)/msvcrt</literal>), though it means you
|
||||
will have to temporarily disable winsock support
|
||||
(<literal>#ifdef</literal> it out in
|
||||
<filename>windows.h</filename>).
|
||||
</para>
|
||||
<para>
|
||||
You should use g++ compiler more recent than g++ 2.95. g++
|
||||
2.95 does not support unnamed structs while the more recent
|
||||
ones do, and this helps a lot. Here are the options worth
|
||||
mentioning:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>-fms-extensions</literal> (helps get more code
|
||||
to compile)
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>-fshort-wchar -DWINE_UNICODE_NATIVE</literal>
|
||||
(helps with Unicode support)
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>-DICOM_USE_COM_INTERFACE_ATTRIBUTE</literal>
|
||||
(to get the COM code to work)
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
<para>
|
||||
When you first reach the link stage you will get a lot of
|
||||
undefined symbol errors. To fix these you will need to go back
|
||||
to the source and <literal>#ifdef</literal>-out more code
|
||||
until you reach a 'closure'. There are also some files that
|
||||
don't need to be compiled.
|
||||
</para>
|
||||
<para>
|
||||
Maybe we will have ready-made makefile here someday...
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
</chapter>
|
||||
|
||||
<!-- Keep this comment at the end of the file
|
||||
Local variables:
|
||||
mode: sgml
|
||||
sgml-parent-document:("winelib-user.sgml" "book" "chapter" "")
|
||||
End:
|
||||
-->
|
|
@ -1,159 +0,0 @@
|
|||
<chapter id="portability-issues">
|
||||
<title id="portability-issues.title">Portability issues</title>
|
||||
|
||||
<sect1 id="unicode">
|
||||
<title id="unicode.title">Unicode</title>
|
||||
|
||||
<para>
|
||||
The <literal>wchar_t</literal> type has different standard
|
||||
sizes in Unix (4 bytes) and Windows (2 bytes). You need a
|
||||
recent gcc version (2.9.7 or later) that supports the
|
||||
<parameter>-fshort-wchar</parameter> option to set the
|
||||
size of <literal>wchar_t</literal> to the one expected
|
||||
by Windows applications.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If you are using Unicode and you want to be able to use
|
||||
standard library calls (e.g. <function>wcslen</function>,
|
||||
<function>wsprintf</function>), then you must use
|
||||
the msvcrt runtime library instead of glibc. The functions in
|
||||
glibc will not work correctly with 16 bit strings.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="C-library">
|
||||
<title id="C-library.title">C library</title>
|
||||
|
||||
<para>
|
||||
There are 2 choices available to you regarding which C library
|
||||
to use: the native glibc C library or the msvcrt C library.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Note that under Wine, the crtdll library is implemented using
|
||||
msvcrt, so there is no benefit in trying to use it.
|
||||
</para>
|
||||
<para>
|
||||
Using glibc in general has the lowest overhead, but this is
|
||||
really only important for file I/O, as many of the functions
|
||||
in msvcrt are simply resolved to glibc.
|
||||
</para>
|
||||
<para>
|
||||
To use glibc, you don't need to make changes to your
|
||||
application; it should work straight away. There are a few
|
||||
situations in which using glibc is not possible:
|
||||
</para>
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
Your application uses Win32 and C library unicode
|
||||
functions.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Your application uses MS specific calls like
|
||||
<function>beginthread()</function>,
|
||||
<function>loadlibrary()</function>, etc.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
You rely on the precise semantics of the calls, for
|
||||
example, returning <literal>-1</literal> rather than
|
||||
non-zero. More likely, your application will rely on calls
|
||||
like <function>fopen()</function> taking a Windows path
|
||||
rather than a Unix one.
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
<para>
|
||||
In these cases you should use msvcrt to provide your C runtime
|
||||
calls.
|
||||
</para>
|
||||
|
||||
<programlisting>import msvcrt.dll</programlisting>
|
||||
|
||||
<para>
|
||||
to your applications <filename>.spec</filename> file. This
|
||||
will cause <command>winebuild</command> to resolve your c
|
||||
library calls to <filename>msvcrt.dll</filename>. Many simple
|
||||
calls which behave the same have been specified as
|
||||
non-importable from msvcrt; in these cases
|
||||
<command>winebuild</command> will not resolve them and the
|
||||
standard linker <command>ld</command> will link to the glibc
|
||||
version instead.
|
||||
</para>
|
||||
<para>
|
||||
In order to avoid warnings in C (and potential errors in C++)
|
||||
from not having prototypes, you may need to use a set of MS
|
||||
compatible header files. These are scheduled for inclusion
|
||||
into Wine but at the time of writing are not available. Until
|
||||
they are, you can try prototyping the functions you need, or
|
||||
just live with the warnings.
|
||||
</para>
|
||||
<para>
|
||||
If you have a set of include files (or when they are available
|
||||
in Wine), you need to use the <parameter>-isystem
|
||||
"include_path"</parameter> flag to gcc to tell it to use your
|
||||
headers in preference to the local system headers.
|
||||
</para>
|
||||
<para>
|
||||
To use option 3, add the names of any symbols that you don't
|
||||
want to use from msvcrt into your applications
|
||||
<filename>.spec</filename> file. For example, if you wanted
|
||||
the MS specific functions, but not file I/O, you could have a
|
||||
list like:
|
||||
</para>
|
||||
|
||||
<programlisting>@ignore = ( fopen fclose fwrite fread fputs fgets )</programlisting>
|
||||
<para>
|
||||
Obviously, the complete list would be much longer. Remember
|
||||
too that some functions are implemented with an underscore in
|
||||
their name and <function>#define</function>d to that name in
|
||||
the MS headers. So you may need to find out the name by
|
||||
examining <filename>dlls/msvcrt/msvcrt.spec</filename> to get
|
||||
the correct name for your <function>@ignore</function> entry.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="porting-compiling">
|
||||
<title id="porting-compiling.title">Compiling Problems</title>
|
||||
<para>
|
||||
If you get undefined references to Win32 API calls when
|
||||
building your application: if you have a VC++
|
||||
<filename>.dsp</filename> file, check it for all the
|
||||
<filename>.lib</filename> files it imports, and add them to
|
||||
your applications <filename>.spec</filename>
|
||||
file. <command>winebuild</command> gives you a warning for
|
||||
unused imports so you can delete the ones you don't need
|
||||
later. Failing that, just import all the DLL's you can find in
|
||||
the <filename>dlls/</filename> directory of the Wine source
|
||||
tree.
|
||||
</para>
|
||||
<para>
|
||||
If you are missing GUIDs at the link stage, add
|
||||
<parameter>-lwine_uuid</parameter> to the link line.
|
||||
</para>
|
||||
<para>
|
||||
gcc is more strict than VC++, especially when compiling
|
||||
C++. This may require you to add casts to your C++ to prevent
|
||||
overloading ambiguities between similar types (such as two
|
||||
overloads that take int and char respectively).
|
||||
</para>
|
||||
<para>
|
||||
If you come across a difference between the Windows headers
|
||||
and Wine's that breaks compilation, try asking for help on
|
||||
<email>wine-devel@winehq.org</email>.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
</chapter>
|
||||
|
||||
<!-- Keep this comment at the end of the file
|
||||
Local variables:
|
||||
mode: sgml
|
||||
sgml-parent-document:("winelib-user.sgml" "book" "chapter" "")
|
||||
End:
|
||||
-->
|
|
@ -1,983 +0,0 @@
|
|||
<chapter id="winelib-toolkit">
|
||||
<title id="winelib-toolkit.title">The Winelib development toolkit</title>
|
||||
|
||||
<sect1 id="winemaker">
|
||||
<title id="winemaker.title">Winemaker</title>
|
||||
|
||||
<sect2 id="vc-projects">
|
||||
<title id="vc-projects.title">Support for Visual C++ projects</title>
|
||||
<para>
|
||||
Unfortunately Winemaker does not support the Visual C++ project
|
||||
files, ...yet. Supporting Visual C++ project files (the
|
||||
<filename>.dsp</filename> and some <filename>.mak</filename> files
|
||||
for older versions of Visual C++) is definitely on
|
||||
the list of important Winemaker improvements as it will allow it to
|
||||
properly detect the defines to be used, any custom include path, the
|
||||
list of libraries to link with, and exactly which source files to use
|
||||
to build a specific target. All things that the current version of
|
||||
Winemaker has to guess or that you have to tell it as will become
|
||||
clear in the next section.
|
||||
</para>
|
||||
<para>
|
||||
When the time comes Winemaker, and its associated build system, will
|
||||
need some extensions to support:
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
per file defines and include paths. Visual C++ projects allow
|
||||
the user to specify compiler options for each individual file
|
||||
being compiled. But this is probably not very frequent so it
|
||||
might not be that important.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
multiple configurations. Visual C++ projects usually have at
|
||||
least a 'Debug' and a 'Release' configuration which are compiled
|
||||
with different compiler options. How exactly we deal with these
|
||||
configurations remains to be determined.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="source-analysis">
|
||||
<title id="source-analysis.title">Winemaker's source analysis</title>
|
||||
<para>
|
||||
Winemaker can do its work even without a Windows makefile or a
|
||||
Visual Studio project to start from (it would not know what to do
|
||||
with a windows makefile anyway). This involves doing many educated
|
||||
guesses which may be wrong. But by and large it works. The purpose
|
||||
of this section is to describe in more details how winemaker
|
||||
proceeds so that you can better understand why it gets things
|
||||
wrong and how to fix it/avoid it.
|
||||
</para>
|
||||
<para>
|
||||
At the core winemaker does a recursive traversal of
|
||||
your source tree looking for targets (things to build) and source
|
||||
files. Let's start with the targets.
|
||||
</para>
|
||||
<para>
|
||||
First are executables and DLLs. Each time it finds one of these in
|
||||
a directory, winemaker puts it in the list of things to build and
|
||||
will later generate a <filename>Makefile</filename> file in this
|
||||
directory. Note that Winemaker also knows about the commonly used
|
||||
<filename>Release</filename> and <filename>Debug</filename>
|
||||
directories, so it will attribute the executables and libraries
|
||||
found in these to their parent directory. When it finds an
|
||||
executable or a DLL winemaker is happy because these give it more
|
||||
information than the other cases described below.
|
||||
</para>
|
||||
<para>
|
||||
If it does not find any executable or DLL winemaker will look for
|
||||
files with a <filename>.mak</filename> extension. If they are not
|
||||
disguised Visual C++ projects (and currently even if they are),
|
||||
winemaker will assume that a target by that name should be built
|
||||
in this directory. But it will not know whether this target is an
|
||||
executable or a library. So it will assume it is of the default
|
||||
type, i.e. a graphical application, which you can override by using
|
||||
the <option>--cuiexe</option> and <option>--dll</option> options.
|
||||
</para>
|
||||
<para>
|
||||
Finally winemaker will check to see if there is a file called
|
||||
<filename>makefile</filename>. If there is, then it will assume
|
||||
that there is exactly one target to build for this directory. But
|
||||
it will not know the name or type of this target. For the type it
|
||||
will do as in the above case. And for the name it will use the
|
||||
directory's name. Actually, if the directory starts with
|
||||
<filename>src</filename> winemaker will try to make use of the name
|
||||
of the parent directory instead.
|
||||
</para>
|
||||
<para>
|
||||
Once the target list for a directory has been established,
|
||||
winemaker will check whether it contains a mix of executables and
|
||||
libraries. If it is so, then winemaker will make it so that each
|
||||
executable is linked with all the libraries of that directory.
|
||||
</para>
|
||||
<para>
|
||||
If the previous two steps don't produce the expected results (or
|
||||
you think they will not) then you should put winemaker in
|
||||
interactive mode (see <xref linkend="interactive"
|
||||
endterm="interactive.title">). This will allow you to specify the
|
||||
target list (and more) for each directory.
|
||||
</para>
|
||||
<para>
|
||||
In each directory winemaker also looks for source files: C, C++
|
||||
or resource files. If it also found targets to build in this
|
||||
directory it will then try to assign each source file to one of
|
||||
these targets based on their names. Source files that do not seem
|
||||
to match any specific target are put in a global list for this
|
||||
directory, see the <literal>EXTRA_xxx</literal> variables in the
|
||||
<filename>Makefile</filename>, and linked with each of the
|
||||
targets. The assumption here is that these source files contain
|
||||
common code which is shared by all the targets.
|
||||
If no targets were found in the directory where these files are
|
||||
located, then they are assigned to the parent's directory. So if a
|
||||
target is found in the parent directory it will also 'inherit' the
|
||||
source files found in its subdirectories.
|
||||
</para>
|
||||
<para>
|
||||
Finally winemaker also looks for more exotic files like
|
||||
<filename>.h</filename> headers, <filename>.inl</filename> files
|
||||
containing inline functions and a few others. These are not put in
|
||||
the regular source file lists since they are not compiled directly.
|
||||
But winemaker will still remember them so that they are processed
|
||||
when the time comes to fix the source files.
|
||||
</para>
|
||||
<para>
|
||||
Fixing the source files is done as soon as winemaker has finished
|
||||
its recursive directory traversal. The two main tasks in this step
|
||||
are fixing the CRLF issues and verifying the case of the include
|
||||
statements.
|
||||
</para>
|
||||
<para>
|
||||
Winemaker makes a backup of each source file (in such a way that
|
||||
symbolic links are preserved), then reads it fixing the CRLF
|
||||
issues and the other issues as it goes. Once it has finished
|
||||
working on a file it checks whether it has done any non
|
||||
CRLF-related modification and deletes the backup file if it did
|
||||
not (or if you used <option>--nobackup</option>).
|
||||
</para>
|
||||
<para>
|
||||
Checking the case of the include statements (of any form,
|
||||
including files referenced by resource files), is done in the
|
||||
context of that source file's project. This way winemaker can use
|
||||
the proper include path when looking for the file that is included.
|
||||
If winemaker fails to find a file in any of the directories of the
|
||||
include path, it will rename it to lowercase on the basis that it
|
||||
is most likely a system header and that all system headers names
|
||||
are lowercase (this can be overridden by using
|
||||
<option>--nolower-include</option>).
|
||||
</para>
|
||||
<para>
|
||||
Finally winemaker generates the <filename>Makefile</filename>
|
||||
files. From the above description
|
||||
you can guess at the items that winemaker may get wrong in
|
||||
this phase: macro definitions, include path, DLL path, DLLs to
|
||||
import, library path, libraries to link with. You can deal with
|
||||
these issues by using winemaker's <option>-D</>, <option>-P</>,
|
||||
<option>-i</>, <option>-I</>, <option>-L</> and <option>-l</>
|
||||
options if they are
|
||||
homogeneous enough between all your targets. Otherwise you may
|
||||
want to use winemaker's <link linkend="interactive">interactive
|
||||
mode</link> so that you can specify different settings for each
|
||||
project / target.
|
||||
</para>
|
||||
<para>
|
||||
For instance, one of the problems you are likely to encounter is
|
||||
that of the <varname>STRICT</varname> macro. Some programs will
|
||||
not compile if <varname>STRICT</varname> is not turned on, and
|
||||
others will not compile if it is. Fortunately all the files in a
|
||||
given source tree use the same setting so that all you have to do
|
||||
is add <literal>-DSTRICT</literal> on winemaker's command line
|
||||
or in the <filename>Makefile</filename> file(s).
|
||||
</para>
|
||||
<para>
|
||||
Finally the most likely reasons for missing or duplicate symbols
|
||||
are:
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
The target is not importing the right set of DLLs, or is not
|
||||
being linked with the right set of libraries. You can avoid
|
||||
this by using winemaker's <option>-P</>, <option>-i</>,
|
||||
<option>-L</option> and <option>-l</> options or adding these
|
||||
DLLs and libraries to the <filename>Makefile</> file.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Maybe you have multiple targets in a single directory and
|
||||
winemaker guessed wrong when trying to match the source files
|
||||
with the targets. The only way to fix this kind of problem is
|
||||
to edit the <filename>Makefile</filename> file manually.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Winemaker assumes you have organized your source files
|
||||
hierarchically. If a target uses source files that are in a
|
||||
sibling directory, e.g. if you link with
|
||||
<filename>../hello/world.o</filename> then you will get missing
|
||||
symbols. Again the only solution is to manually edit the
|
||||
<filename>Makefile</filename> file.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="interactive">
|
||||
<title id="interactive.title">The interactive mode</title>
|
||||
<para>
|
||||
what is it,
|
||||
when to use it,
|
||||
how to use it
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="Makefile">
|
||||
<title id="Makefile.title">The Makefile files</title>
|
||||
<para>
|
||||
The <filename>Makefile</filename> is your makefile.
|
||||
So this is the file to modify if you want to customize things.
|
||||
Here's a detailed description of its content:
|
||||
</para>
|
||||
<programlisting>
|
||||
### Generic autoconf variables
|
||||
|
||||
TOPSRCDIR = @top_srcdir@
|
||||
TOPOBJDIR = .
|
||||
SRCDIR = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
</programlisting>
|
||||
<para>
|
||||
The above is part of the standard autoconf boiler-plate. These
|
||||
variables make it possible to have per-architecture directories for
|
||||
compiled files and other similar goodies (But note that this kind
|
||||
of functionality has not been tested with winemaker generated
|
||||
<filename>Makefile</filename> files yet).
|
||||
</para>
|
||||
<programlisting>
|
||||
SUBDIRS =
|
||||
DLLS =
|
||||
EXES = hello.exe
|
||||
</programlisting>
|
||||
<para>
|
||||
This is where the targets for this directory are listed. The names
|
||||
are pretty self-explanatory. <varname>SUBDIRS</varname> is usually
|
||||
only present in the top-level makefile. For libraries and
|
||||
executables, specify the full name, including the '.dll' or '.exe'
|
||||
extension. Note that these names must be in all lowercase.
|
||||
</para>
|
||||
<programlisting>
|
||||
### Global settings
|
||||
|
||||
DEFINES = -DSTRICT
|
||||
INCLUDE_PATH =
|
||||
DLL_PATH =
|
||||
LIBRARY_PATH =
|
||||
LIBRARIES =
|
||||
</programlisting>
|
||||
<para>
|
||||
This section contains the global compilation settings: they apply
|
||||
to all the targets in this makefile. The <varname>LIBRARIES</>
|
||||
variable allows you to specify additional Unix libraries to link
|
||||
with. Note that you would normally not specify Winelib libraries
|
||||
there. To link with a Winelib library, one uses the <varname>DLLS</>
|
||||
variables of the Makefile. The exception is for C++ libraries where
|
||||
you currently don't have a choice but to link with them in the
|
||||
Unix sense. One library you are likely to find here is
|
||||
<literal>mfc</> (note, the '-l' is omitted).
|
||||
</para>
|
||||
<para>
|
||||
The other variable
|
||||
names should be self-explanatory. You can also use three additional
|
||||
variables that are usually not present in the file:
|
||||
<varname>CEXTRA</varname>, <varname>CXXEXTRA</varname> and
|
||||
<varname>WRCEXTRA</varname> which allow you to specify additional
|
||||
flags for, respectively, the C compiler, the C++ compiler and the
|
||||
resource compiler. Finally note that all these variable contain
|
||||
the option's name.
|
||||
</para>
|
||||
<para>
|
||||
Then come one section per target, each describing the various
|
||||
components that target is made of.
|
||||
</para>
|
||||
<programlisting>
|
||||
### hello.exe sources and settings
|
||||
|
||||
hello_exe_C_SRCS = hello.c
|
||||
hello_exe_CXX_SRCS =
|
||||
hello_exe_RC_SRCS =
|
||||
hello_exe_SPEC_SRCS =
|
||||
</programlisting>
|
||||
<para>
|
||||
Each section will start with a comment indicating the name of the
|
||||
target. Then come a series of variables prefixed with the name of
|
||||
that target. Note that the name of the prefix may be slightly
|
||||
different from that of the target because of restrictions on the
|
||||
variable names.
|
||||
</para>
|
||||
<para>
|
||||
The above variables list the sources that are used togenerate the
|
||||
target. Note that there should only be one resource file in
|
||||
<varname>RC_SRCS</varname>, and that <varname>SPEC_SRCS</varname>
|
||||
will usually be empty for executables, and will contain a single
|
||||
spec file for libraries.
|
||||
</para>
|
||||
<programlisting>
|
||||
hello_exe_DLL_PATH =
|
||||
hello_exe_DLLS =
|
||||
hello_exe_LIBRARY_PATH =
|
||||
hello_exe_LIBRARIES =
|
||||
hello_exe_DEPENDS =
|
||||
</programlisting>
|
||||
<para>
|
||||
The above variables specify how to link the target. Note that they
|
||||
add to the global settings we saw at the beginning of this file.
|
||||
</para>
|
||||
<para>
|
||||
The <varname>DLLS</> field is where you would enumerate the list of
|
||||
DLLs that executable imports. It should contain the full DLL name
|
||||
including the '.dll' extension, but not the '-l' option.
|
||||
</para>
|
||||
<para>
|
||||
<varname>DEPENDS</>, when present, specifies a list of other
|
||||
targets that this target depends on. Winemaker will automatically
|
||||
fill this field when an executable and a library are built in the
|
||||
same directory.
|
||||
</para>
|
||||
<programlisting>
|
||||
hello_exe_OBJS = $(hello_exe_C_SRCS:.c=.o) \
|
||||
$(hello_exe_CXX_SRCS:.cpp=.o) \
|
||||
$(EXTRA_OBJS)
|
||||
</programlisting>
|
||||
<para>
|
||||
The above just builds a list of all the object files that
|
||||
correspond to this target. This list is later used for the link
|
||||
command.
|
||||
</para>
|
||||
<programlisting>
|
||||
### Global source lists
|
||||
|
||||
C_SRCS = $(hello_exe_C_SRCS)
|
||||
CXX_SRCS = $(hello_exe_CXX_SRCS)
|
||||
RC_SRCS = $(hello_exe_RC_SRCS)
|
||||
SPEC_SRCS = $(hello_exe_SPEC_SRCS)
|
||||
</programlisting>
|
||||
<para>
|
||||
This section builds 'summary' lists of source files. These lists are
|
||||
used by the <filename>Make.rules</filename> file.
|
||||
</para>
|
||||
<note><para>
|
||||
FIXME:The following is not up-to-date.
|
||||
</para></note>
|
||||
<programlisting>
|
||||
### Generic autoconf targets
|
||||
|
||||
all: $(DLLS:%=%.so) $(EXES:%=%.so)
|
||||
|
||||
@MAKE_RULES@
|
||||
|
||||
install::
|
||||
for i in $(EXES); do $(INSTALL_PROGRAM) $$i $(bindir); done
|
||||
for i in $(EXES:%=%.so) $(DLLS); do $(INSTALL_LIBRARY) $$i $(libdir); done
|
||||
|
||||
uninstall::
|
||||
for i in $(EXES); do $(RM) $(bindir)/$$i;done
|
||||
for i in $(EXES:%=%.so) $(DLLS); do $(RM) $(libdir)/$$i;done
|
||||
</programlisting>
|
||||
<para>
|
||||
The above first defines the default target for this makefile. Here
|
||||
it consists in trying to build all the targets. Then it includes
|
||||
the <filename>Make.rules</filename> file which contains the build
|
||||
logic, and provides a few more standard targets to install /
|
||||
uninstall the targets.
|
||||
</para>
|
||||
<programlisting>
|
||||
### Target specific build rules
|
||||
|
||||
$(hello_SPEC_SRCS:.spec=.tmp.o): $(hello_OBJS)
|
||||
$(LDCOMBINE) $(hello_OBJS) -o $@
|
||||
-$(STRIP) $(STRIPFLAGS) $@
|
||||
|
||||
$(hello_SPEC_SRCS:.spec=.spec.c): $(hello_SPEC_SRCS:.spec) $(hello_SPEC_SRCS:.spec=.tmp.o) $(hello_RC_SRCS:.rc=.res)
|
||||
$(WINEBUILD) -fPIC $(hello_LIBRARY_PATH) $(WINE_LIBRARY_PATH) -sym $(hello_SPEC_SRCS:.spec=.tmp.o) -o $@ -spec $(hello_SPEC_SRCS)
|
||||
|
||||
hello.so: $(hello_SPEC_SRCS:.spec=.spec.o) $(hello_OBJS) $(hello_DEP
|
||||
ENDS)
|
||||
$(LDSHARED) $(LDDLLFLAGS) -o $@ $(hello_OBJS) $(hello_SPEC_SRCS:.spec=.spec.o) $(hello_LIBRARY_PATH) $(hello_LIBRARIES:%=-l%) $(DLL_LINK) $(LIBS)
|
||||
test -f hello || $(LN_S) $(WINE) hello
|
||||
</programlisting>
|
||||
<para>
|
||||
Then come additional directives to link the executables and
|
||||
libraries. These are pretty much standard and you should not need
|
||||
to modify them.
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="wrc">
|
||||
<title id="wrc.title">Compiling resource files: WRC</title>
|
||||
<para>
|
||||
To compile resources you should use the Wine Resource Compiler,
|
||||
wrc for short, which produces a binary <filename>.res</filename>
|
||||
file. This resource file is then used by winebuild when compiling
|
||||
the spec file (see <xref linkend="spec-file"
|
||||
endterm="spec-file.title">).
|
||||
</para>
|
||||
<para>
|
||||
Again the makefiles generated by winemaker take care of this for you.
|
||||
But if you were to write your own makefile you would put something
|
||||
like the following:
|
||||
</para>
|
||||
<programlisting>
|
||||
WRC=$(WINE_DIR)/tools/wrc/wrc
|
||||
|
||||
WINELIB_FLAGS = -I$(WINE_DIR)/include -DWINELIB -D_REENTRANT
|
||||
WRCFLAGS = -r -L
|
||||
|
||||
.SUFFIXES: .rc .res
|
||||
|
||||
.rc.res:
|
||||
$(WRC) $(WRCFLAGS) $(WINELIB_FLAGS) -o $@ $<
|
||||
</programlisting>
|
||||
<para>
|
||||
There are two issues you are likely to encounter with resource files.
|
||||
</para>
|
||||
<para>
|
||||
The first problem is with the C library headers. WRC does not know
|
||||
where these headers are located. So if an RC file, of a file it
|
||||
includes, references such a header you will get a 'file not found'
|
||||
error from wrc. Here are a few ways to deal with this:
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
The solution traditionally used by the Winelib headers is to
|
||||
enclose the offending include statement in an
|
||||
<literal>#ifndef RC_INVOKED</literal> statement where
|
||||
<varname>RC_INVOKED</varname> is a macro name which is
|
||||
automatically defined by wrc.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Alternately you can add one or more <option>-I</option> directive
|
||||
to your wrc command so that it finds you system files. For
|
||||
instance you may add <literal>-I/usr/include
|
||||
-I/usr/lib/gcc-lib/i386-linux/2.95.2/include</literal> to cater
|
||||
to both C and C++ headers. But this supposes that you know where
|
||||
these header files reside which decreases the portability of your
|
||||
makefiles to other platforms (unless you automatically detect all
|
||||
the necessary directories in the autoconf script).
|
||||
</para>
|
||||
<para>
|
||||
Or you could use the C/C++ compiler to perform the preprocessing.
|
||||
To do so, simply modify your makefile as follows:
|
||||
</para>
|
||||
<programlisting>
|
||||
.rc.res:
|
||||
$(CC) $(CC_OPTS) -DRC_INVOKED -E -x c $< | $(WRC) -N $(WRCFLAGS) $(WINELIB_FLAGS) -o $@
|
||||
|
||||
</programlisting>
|
||||
<!-- FIXME: does this still cause problems for the line numbers? -->
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<para>
|
||||
The second problem is that the headers may contain constructs that
|
||||
WRC fails to understand. A typical example is a function which return
|
||||
a 'const' type. WRC expects a function to be two identifiers followed
|
||||
by an opening parenthesis. With the const this is three identifiers
|
||||
followed by a parenthesis and thus WRC is confused (note: WRC should
|
||||
in fact ignore all this like the windows resource compiler does).
|
||||
The current work-around is to enclose offending statement(s) in an
|
||||
<literal>#ifndef RC_INVOKED</literal>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Using GIF files in resources is problematic. For best results,
|
||||
convert them to BMP and change your <filename>.res</filename>
|
||||
file.
|
||||
</para>
|
||||
<para>
|
||||
If you use common controls/dialogs in your resource files, you
|
||||
will need to add <function>#include <commctrl.h></function>
|
||||
after the <function>#include <windows.h></function> line,
|
||||
so that <command>wrc</command> knows the values of control
|
||||
specific flags.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="wmc">
|
||||
<title id="wmc.title">Compiling message files: WMC</title>
|
||||
<para>
|
||||
how does one use it???
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="spec-file">
|
||||
<title id="spec-file.title">The Spec file</title>
|
||||
|
||||
<sect2 id="spec-intro">
|
||||
<title id="spec-intro.title">Introduction</title>
|
||||
<para>
|
||||
In Windows the program's life starts either when its
|
||||
<function>main</function> is called, for console applications, or
|
||||
when its <function>WinMain</function> is called, for windows
|
||||
applications in the 'windows' subsystem. On Unix it is always
|
||||
<function>main</function> that is called. Furthermore in Winelib it
|
||||
has some special tasks to accomplish, such as initializing Winelib,
|
||||
that a normal <function>main</function> does not have to do.
|
||||
</para>
|
||||
<para>
|
||||
Furthermore windows applications and libraries contain some
|
||||
information which are necessary to make APIs such as
|
||||
<function>GetProcAddress</function> work. So it is necessary to
|
||||
duplicate these data structures in the Unix world to make these
|
||||
same APIs work with Winelib applications and libraries.
|
||||
</para>
|
||||
<para>
|
||||
The spec file is there to solve the semantic gap described above.
|
||||
It provides the <function>main</function> function that initializes
|
||||
Winelib and calls the module's <function>WinMain</function> /
|
||||
<function>DllMain</function>, and it contains information about
|
||||
each API exported from a Dll so that the appropriate tables can be
|
||||
generated.
|
||||
</para>
|
||||
<para>
|
||||
A typical spec file will look something like this:
|
||||
</para>
|
||||
<screen>
|
||||
init WinMain
|
||||
rsrc resource.res
|
||||
</screen>
|
||||
<para>
|
||||
And here are the entries you will probably want to change:
|
||||
</para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>init</term>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>init</literal> defines what is the entry point of
|
||||
that module. For a library this is customarily set to
|
||||
<literal>DllMain</literal>, for a console application this
|
||||
is <literal>main</literal> and for a graphical application
|
||||
this is <literal>WinMain</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>rsrc</term>
|
||||
<listitem>
|
||||
<para>
|
||||
This item specifies the name of the compiled resource file
|
||||
to link with your module. If your resource file is called
|
||||
<filename>hello.rc</filename> then the wrc compilation step
|
||||
(see <xref linkend="wrc" endterm="wrc.title">) will generate
|
||||
a file called <filename>hello.res</filename>. This is the
|
||||
name you must provide here. Note that because of this you
|
||||
cannot compile the spec file before you have compiled the
|
||||
resource file. So you should put a rule like the following
|
||||
in your makefile:
|
||||
</para>
|
||||
<programlisting>
|
||||
hello.spec.c: hello.res
|
||||
</programlisting>
|
||||
<para>
|
||||
If your project does not have a resource file then you must
|
||||
omit this entry altogether.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>@</term>
|
||||
<listitem>
|
||||
<note><para>
|
||||
FIXME: You must now export functions from DLLs.
|
||||
</para></note>
|
||||
<para>
|
||||
This entry is not shown above because it is not always
|
||||
necessary. In fact it is only necessary to export functions
|
||||
when you plan to dynamically load the library with
|
||||
<function>LoadLibrary</function> and then do a
|
||||
<function>GetProcAddress</function> on these functions.
|
||||
This is not necessary if you just plan on linking with the
|
||||
library and calling the functions normally. For more details
|
||||
about this see: <xref linkend="spec-reference"
|
||||
endterm="spec-reference.title">.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="spec-compiling">
|
||||
<title id="spec-compiling.title">Compiling it</title>
|
||||
<note><para>
|
||||
FIXME: This section is very outdated and does not correctly
|
||||
describe the current use of winebuild and spec files. In
|
||||
particular, with recent versions of winebuild most of the
|
||||
information that used to be in the spec files is now specified on
|
||||
the command line.
|
||||
</para></note>
|
||||
<para>
|
||||
Compiling a spec file is a two step process. It is first
|
||||
converted into a C file by winebuild, and then compiled into an
|
||||
object file using your regular C compiler. This is all taken
|
||||
care of by the winemaker generated makefiles of course. But
|
||||
here's what it would like if you had to do it by hand:
|
||||
</para>
|
||||
<screen>
|
||||
WINEBUILD=$(WINE_DIR)/tools/winebuild
|
||||
|
||||
.SUFFIXES: .spec .spec.c .spec.o
|
||||
|
||||
.spec.spec.c:
|
||||
$(WINEBUILD) -fPIC -o $@ -spec $<
|
||||
|
||||
.spec.c.spec.o:
|
||||
$(CC) -c -o $*.spec.o $<
|
||||
</screen>
|
||||
<para>
|
||||
Nothing really complex there. Just don't forget the
|
||||
<literal>.SUFFIXES</literal> statement, and beware of the tab if
|
||||
you copy this straight to your Makefile.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="spec-reference">
|
||||
<title id="spec-reference.title">More details</title>
|
||||
|
||||
<para>
|
||||
Here is a more detailed description of the spec file's format.
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
# comment text
|
||||
</programlisting>
|
||||
<para>
|
||||
Anything after a '#' will be ignored as comments.
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
init FUNCTION
|
||||
</programlisting>
|
||||
<para>
|
||||
This field is optional and specific to Win32 modules. It
|
||||
specifies a function which will be called when the DLL is loaded
|
||||
or the executable started.
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
rsrc RES_FILE
|
||||
</programlisting>
|
||||
<para>
|
||||
This field is optional. If present it specifies the name of the
|
||||
.res file containing the compiled resources. See <xref
|
||||
linkend="wrc" endterm="wrc.title"> for details on compiling a
|
||||
resource file.
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
ORDINAL VARTYPE EXPORTNAME (DATA [DATA [DATA [...]]])
|
||||
2 byte Variable(-1 0xff 0 0)
|
||||
</programlisting>
|
||||
<para>
|
||||
This field can be present zero or more times.
|
||||
Each instance defines data storage at the ordinal specified. You
|
||||
may store items as bytes, 16-bit words, or 32-bit words.
|
||||
<literal>ORDINAL</literal> is replaced by the ordinal number
|
||||
corresponding to the variable. <literal>VARTYPE</literal> should
|
||||
be <literal>byte</literal>, <literal>word</literal> or
|
||||
<literal>long</literal> for 8, 16, or 32 bits respectively.
|
||||
<literal>EXPORTNAME</literal> will be the name available for
|
||||
dynamic linking. <literal>DATA</literal> can be a decimal number
|
||||
or a hex number preceded by "0x". The example defines the
|
||||
variable <literal>Variable</literal> at ordinal 2 and containing
|
||||
4 bytes.
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
ORDINAL equate EXPORTNAME DATA
|
||||
</programlisting>
|
||||
<para>
|
||||
This field can be present zero or more times.
|
||||
Each instance defines an ordinal as an absolute value.
|
||||
<literal>ORDINAL</literal> is replaced by the ordinal number
|
||||
corresponding to the variable. <literal>EXPORTNAME</literal> will
|
||||
be the name available for dynamic linking.
|
||||
<literal>DATA</literal> can be a decimal number or a hex number
|
||||
preceded by "0x".
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
ORDINAL FUNCTYPE EXPORTNAME([ARGTYPE [ARGTYPE [...]]]) HANDLERNAME
|
||||
100 pascal CreateWindow(ptr ptr long s_word s_word s_word s_word
|
||||
word word word ptr)
|
||||
WIN_CreateWindow
|
||||
101 pascal GetFocus() WIN_GetFocus()
|
||||
</programlisting>
|
||||
<para>
|
||||
This field can be present zero or more times.
|
||||
Each instance defines a function entry point. The prototype
|
||||
defined by <literal>EXPORTNAME ([ARGTYPE [ARGTYPE [...]]])</literal>
|
||||
specifies the name available for dynamic linking and the format
|
||||
of the arguments. <literal>ORDINAL</literal> is replaced
|
||||
by the ordinal number corresponding to the function, or
|
||||
<literal>@</literal> for automatic ordinal allocation (Win32 only).
|
||||
</para>
|
||||
<para>
|
||||
<literal>FUNCTYPE</literal> should be one of:
|
||||
</para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>pascal16</term>
|
||||
<listitem>
|
||||
<para>
|
||||
for a Win16 function returning a 16-bit value
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>pascal</term>
|
||||
<listitem>
|
||||
<para>
|
||||
for a Win16 function returning a 32-bit value
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>register</term>
|
||||
<listitem>
|
||||
<para>
|
||||
for a function using CPU register to pass arguments
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>interrupt</term>
|
||||
<listitem>
|
||||
<para>
|
||||
for a Win16 interrupt handler routine
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>stdcall</term>
|
||||
<listitem>
|
||||
<para>
|
||||
for a normal Win32 function
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>cdecl</term>
|
||||
<listitem>
|
||||
<para>
|
||||
for a Win32 function using the C calling convention
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>varargs</term>
|
||||
<listitem>
|
||||
<para>
|
||||
for a Win32 function taking a variable number of arguments
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<para>
|
||||
<literal>ARGTYPE</literal> should be one of:
|
||||
</para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>word</term>
|
||||
<listitem>
|
||||
<para>
|
||||
for a 16 bit word
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>long</term>
|
||||
<listitem>
|
||||
<para>
|
||||
a 32 bit value
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>ptr</term>
|
||||
<listitem>
|
||||
<para>
|
||||
for a linear pointer
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>str</term>
|
||||
<listitem>
|
||||
<para>
|
||||
for a linear pointer to a null-terminated string
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>s_word</term>
|
||||
<listitem>
|
||||
<para>
|
||||
for a 16 bit signed word
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>segptr</term>
|
||||
<listitem>
|
||||
<para>
|
||||
for a segmented pointer
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>segstr</term>
|
||||
<listitem>
|
||||
<para>
|
||||
for a segmented pointer to a null-terminated string
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>wstr</term>
|
||||
<listitem>
|
||||
<para>
|
||||
for a linear pointer to a null-terminated wide
|
||||
(16-bit Unicode) string
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<para>
|
||||
Only <literal>ptr</literal>, <literal>str</literal>,
|
||||
<literal>wstr</literal> and
|
||||
<literal>long</literal> are valid for Win32 functions.
|
||||
<literal>HANDLERNAME</literal> is the name of the actual Wine
|
||||
function that will process the request in 32-bit mode.
|
||||
</para>
|
||||
<para>
|
||||
Strings should almost always map to str,
|
||||
wide strings - wstr.
|
||||
As the general rule it depends on whether the
|
||||
parameter is IN, OUT or IN/OUT.
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
IN: str/wstr
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
OUT: ptr
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
IN/OUT: str/wstr
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<para>
|
||||
It is for debug messages. If the parameter is OUT
|
||||
it might not be initialized and thus it should not
|
||||
be printed as a string.
|
||||
</para>
|
||||
<para>
|
||||
The two examples define an entry point for the
|
||||
<function>CreateWindow</function> and <function>GetFocus</function>
|
||||
calls respectively. The ordinals used are just examples.
|
||||
</para>
|
||||
<para>
|
||||
To declare a function using a variable number of arguments in
|
||||
Win16, specify the function as taking no arguments. The arguments
|
||||
are then available with CURRENT_STACK16->args. In Win32, specify
|
||||
the function as <literal>varargs</literal> and declare it with a
|
||||
'...' parameter in the C file. See the wsprintf* functions in
|
||||
<filename>user.spec</filename> and
|
||||
<filename>user32.spec</filename> for an example.
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
ORDINAL stub EXPORTNAME
|
||||
</programlisting>
|
||||
<para>
|
||||
This field can be present zero or more times.
|
||||
Each instance defines a stub function. It makes the ordinal
|
||||
available for dynamic linking, but will terminate execution with
|
||||
an error message if the function is ever called.
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
ORDINAL extern EXPORTNAME SYMBOLNAME
|
||||
</programlisting>
|
||||
<para>
|
||||
This field can be present zero or more times.
|
||||
Each instance defines an entry that simply maps to a Wine symbol
|
||||
(variable or function); <literal>EXPORTNAME</literal> will point
|
||||
to the symbol <literal>SYMBOLNAME</literal> that must be defined
|
||||
in C code. This type only works with Win32.
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
ORDINAL forward EXPORTNAME SYMBOLNAME
|
||||
</programlisting>
|
||||
<para>
|
||||
This field can be present zero or more times.
|
||||
Each instance defines an entry that is forwarded to another entry
|
||||
point (kind of a symbolic link). <literal>EXPORTNAME</literal>
|
||||
will forward to the entry point <literal>SYMBOLNAME</literal>
|
||||
that must be of the form <literal>DLL.Function</literal>. This
|
||||
type only works with Win32.
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="linking">
|
||||
<title id="linking.title">Linking it all together</title>
|
||||
<note><para>
|
||||
FIXME:The following is not up-to-date.
|
||||
</para></note>
|
||||
<para>
|
||||
To link an executable you need to link together: your object files,
|
||||
the spec file, any Windows libraries that your application depends
|
||||
on, gdi32 for instance, and any additional library that you use. All
|
||||
the libraries you link with should be available as '.so' libraries.
|
||||
If one of them is available only in '.dll' form then consult
|
||||
<xref linkend="bindlls" endterm="bindlls.title">.
|
||||
</para>
|
||||
<para>
|
||||
It is also when attempting to link your executable that you will
|
||||
discover whether you have missing symbols or not in your custom
|
||||
libraries. On Windows when you build a library, the linker will
|
||||
immediately tell you if a symbol it is supposed to export is
|
||||
undefined. In Unix, and in Winelib, this is not the case. The symbol
|
||||
will silently be marked as undefined and it is only when you try to
|
||||
produce an executable that the linker will verify all the symbols are
|
||||
accounted for.
|
||||
</para>
|
||||
<para>
|
||||
So before declaring victory when first converting a library to
|
||||
Winelib, you should first try to link it to an executable (but you
|
||||
would have done that to test it anyway, right?). At this point you
|
||||
may discover some undefined symbols that you thought were implemented
|
||||
by the library. Then, you to the library sources and fix it. But you
|
||||
may also discover that the missing symbols are defined in, say,
|
||||
gdi32. This is because you did not link the said library with gdi32.
|
||||
One way to fix it is to link this executable, and any other that also
|
||||
uses your library, with gdi32. But it is better to go back to your
|
||||
library's makefile and explicitly link it with gdi32.
|
||||
</para>
|
||||
<para>
|
||||
As you will quickly notice, this has unfortunately not been
|
||||
(completely) done for Winelib's own libraries. So if an application
|
||||
must link with ole32, you will also need to link with advapi32,
|
||||
rpcrt4 and others even if you don't use them directly. This can be
|
||||
annoying and hopefully will be fixed soon (feel free to submit a
|
||||
patch).
|
||||
</para>
|
||||
<!-- FIXME: try to give some sort of concrete example -->
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
||||
<!-- Keep this comment at the end of the file
|
||||
Local variables:
|
||||
mode: sgml
|
||||
sgml-parent-document:("winelib-user.sgml" "book" "chapter" "")
|
||||
End:
|
||||
-->
|
|
@ -1,38 +0,0 @@
|
|||
<!doctype book PUBLIC "-//OASIS//DTD DocBook V3.1//EN" [
|
||||
|
||||
<!entity intro SYSTEM "winelib-intro.sgml">
|
||||
<!entity porting SYSTEM "winelib-porting.sgml">
|
||||
<!entity toolkit SYSTEM "winelib-toolkit.sgml">
|
||||
<!entity mfc SYSTEM "winelib-mfc.sgml">
|
||||
<!entity bindlls SYSTEM "winelib-bindlls.sgml">
|
||||
|
||||
]>
|
||||
|
||||
<book id="index">
|
||||
<bookinfo>
|
||||
<title>Winelib User's Guide</title>
|
||||
<!-- Until we learn how to format this thing nicely,
|
||||
we can't really include it -->
|
||||
<!--authorgroup>
|
||||
<author>
|
||||
<firstname>Wilbur</firstname>
|
||||
<surname>Dale</surname>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Francois</firstname>
|
||||
<surname>Gouget</surname>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>John</firstname>
|
||||
<surname>Sheets</surname>
|
||||
</author>
|
||||
<authorgroup-->
|
||||
</bookinfo>
|
||||
|
||||
&intro;
|
||||
&porting;
|
||||
&toolkit;
|
||||
&mfc;
|
||||
&bindlls;
|
||||
|
||||
</book>
|
Loading…
Add table
Reference in a new issue