Moved the SGML documentation over to SourceForge.

oldstable
Dimi Paun 2005-05-10 13:26:14 +00:00 committed by Alexandre Julliard
parent 15ac6847e0
commit 12f9bb7ab2
40 changed files with 8 additions and 23997 deletions

36
README
View File

@ -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
View File

@ -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

View File

@ -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 ****

View File

@ -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

View File

@ -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:

View File

@ -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>

View File

@ -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 &lt;g&gt;.
</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:
-->

View File

@ -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&amp;lr=&amp;ie=UTF-8&amp;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&amp;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>&lt;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

View File

@ -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

View File

@ -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 &lt;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 &lt;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

View File

@ -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">-&gt;</entry>
<entry>"-adobe-helvetica-"</entry>
</row>
<row>
<entry>"MS Serif"</entry>
<entry align="center">-&gt;</entry>
<entry>"-bitstream-charter-"</entry>
</row>
<row>
<entry>"Times New Roman"</entry>
<entry align="center">-&gt;</entry>
<entry>"-adobe-times-"</entry>
</row>
<row>
<entry>"Arial"</entry>
<entry align="center">-&gt;</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] &lt;, optional "mask X font" flag&gt;
</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">-&gt;</entry>
<entry>"International"</entry>
</row>
<row>
<entry>-adobe-helvetica-...</entry>
<entry align="center">-&gt;</entry>
<entry>"Helvetica"</entry>
</row>
<row>
<entry>-adobe-utopia-...</entry>
<entry align="center">-&gt;</entry>
<entry>"Utopia"</entry>
</row>
<row>
<entry>-misc-fixed-...</entry>
<entry align="center">-&gt;</entry>
<entry>"Fixed"</entry>
</row>
<row>
<entry>-...</entry>
<entry align="center">-&gt;</entry>
<entry></entry>
</row>
<row>
<entry>-sony-fixed-...</entry>
<entry align="center">-&gt;</entry>
<entry>"Sony Fixed"</entry>
</row>
<row>
<entry>-...</entry>
<entry align="center">-&gt;</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">-&gt;</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 = &lt;file with metrics&gt;
</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 = &lt;integer value&gt;
</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:
-->

View File

@ -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:
-->

View File

@ -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>

View File

@ -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

View File

@ -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:
-->

View File

@ -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:
-->

View File

@ -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:
-->

View File

@ -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:
-->

View File

@ -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&lt;n&gt;</title>
<para>
Sets the debug level for debug output in the terminal that
wineserver got started in at level &lt;n&gt;.
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 &amp; user backend</entry>
<entry>Wineconsole &amp; 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 &amp; 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:
-->

View File

@ -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:\&gt;</>cd dlls\kernel\tests\Output\Win32_MSVC_Headers
<prompt>C:\wine\dlls\kernel\tests\Output\Win32_MSVC_Headers&gt;</> 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 &lt;wine/test.h&gt;
#include &lt;winbase.h&gt;
/* 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,&amp;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,&amp;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:
-->

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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:&nbsp;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
&lt;foo.h&gt;</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 &lt;foo.h&gt;
</programlisting>
<para>
to
</para>
<programlisting>
#ifdef HAVE_FOO_H
#include &lt;foo.h&gt;
#elif defined (HAVE_BAR_H)
#include &lt;bar.h&gt;
#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 "&amp;" means that the next
character will be highlighted and that pressing that
letter will select the item. You should place these
"&amp;" 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:
-->

View File

@ -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

View File

@ -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&gt; &gt;(sed 's/^[^:]*:io:[^ ]* //' &gt; 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 &gt; log2
</programlisting>
<para>
The trace has the basic form of
</para>
<programlisting>
XXXX &gt; 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>
&gt; data was written to the port
&lt; 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 &gt; 55 @ 0297:01ec
0x37a &gt; 05 @ 0297:01f5
0x379 &lt; 8f @ 0297:01fa
0x37a &gt; 04 @ 0297:0211
0x378 &gt; aa @ 0297:01ec
0x37a &gt; 05 @ 0297:01f5
0x379 &lt; 8f @ 0297:01fa
0x37a &gt; 04 @ 0297:0211
0x378 &gt; 00 @ 0297:01ec
0x37a &gt; 05 @ 0297:01f5
0x379 &lt; 8f @ 0297:01fa
0x37a &gt; 04 @ 0297:0211
0x378 &gt; 00 @ 0297:01ec
0x37a &gt; 05 @ 0297:01f5
0x379 &lt; 8f @ 0297:01fa
0x37a &gt; 04 @ 0297:0211
0x378 &gt; 00 @ 0297:01ec
0x37a &gt; 05 @ 0297:01f5
0x379 &lt; 8f @ 0297:01fa
0x37a &gt; 04 @ 0297:0211
0x378 &gt; 00 @ 0297:01ec
0x37a &gt; 05 @ 0297:01f5
0x379 &lt; 8f @ 0297:01fa
0x37a &gt; 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 &lt; 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 &lt;campbell@torque.net&gt; */
#include &lt;stdio.h&gt;
#include &lt;string.h&gt;
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 &gt; 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 &lt; 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-&lt;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_", &amp;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:
-->

View File

@ -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-&gt;parent</varname>) points to the desktop
window.
</para>
<screen>
Desktop window - root window
| \ `-.
| \ `-.
popup -&gt; wnd1 -&gt; wnd2 - top level windows
| \ `-. `-.
| \ `-. `-.
child1 child2 -&gt; 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-&gt;popup-&gt;child2-&gt;child3-&gt;wnd1-&gt;child4-&gt;wnd2-&gt;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 | | =&gt; | | | - 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 |_________ | =&gt; | ...|___|..
| | | | | : | |
|------' | | | : '---'
| | 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 &lt; , . -
Ctrl Alt Spacebar AltGr Ctrl
</screen>
<para>
Note the 102nd key, which is the <keycap>&lt;></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",",;",".:","-_",
"&lt;>"
};
</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, &amp;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:
-->

View File

@ -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 &lt;3rd party library&gt; so that it can be
* used by &lt;the application&gt;
*
* Currently this file makes no attempt to be a full wrapper for the &lt;3rd
* party library&gt;; 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 &lt;3rd party&gt; libraries (currently libxxxx.so and
* libyyyy.so)
*/
#include &lt; &lt;3rd party linux header&gt; &gt;
#include &lt;windef.h&gt; /* Part of the Wine header files */
/* This declaration is as defined in the spec file. It is deliberately not
* specified in terms of &lt;3rd party&gt; 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 = &lt;3rd party linux function&gt; (a, b, c, &amp;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:
-->

View File

@ -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 &lt;root_dir&gt;</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:
-->

View File

@ -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:
-->

View File

@ -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:
-->

View File

@ -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 &lt;commctrl.h></function>
after the <function>#include &lt;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:
-->

View File

@ -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>