Commit d9e064fd authored by John R. Sheets's avatar John R. Sheets Committed by Alexandre Julliard

Documentation update.

parent e6758871
......@@ -4,6 +4,7 @@ SRCDIR = @srcdir@
VPATH = @srcdir@
MODULE = none
BOOKNAME = wine-doc
DB2HTML = $(SRCDIR)/db2html-winehq
EXTRASUBDIRS = samples status
......@@ -14,14 +15,18 @@ BOOK_SRCS = \
compiling.sgml \
configuring.sgml \
consoles.sgml \
cvs-regression.sgml \
debugger.sgml \
debugging.sgml \
dlls.sgml \
documentation.sgml \
fonts.sgml \
getting.sgml \
i18n.sgml \
implementation.sgml \
installing.sgml \
introduction.sgml \
ole.sgml \
opengl.sgml \
packaging.sgml \
patches.sgml \
......@@ -42,13 +47,13 @@ all: $(BOOK_TARGETS)
@MAKE_RULES@
$(BOOKNAME)/index.html: $(BOOK_SRCS)
db2html $(BOOKNAME).sgml
$(DB2HTML) $(BOOKNAME).sgml
$(BOOKNAME).pdf: $(BOOK_SRCS)
db2pdf $(BOOKNAME).sgml
db2pdf $(BOOKNAME).sgml > /dev/null 2>&1
$(BOOKNAME).ps: $(BOOK_SRCS)
db2ps $(BOOKNAME).sgml
db2ps $(BOOKNAME).sgml > /dev/null 2>&1
install::
$(INSTALL) -d $(mandir)/man$(prog_manext)
......
......@@ -5,7 +5,9 @@
<sect1 id="basic-overview">
<title>Basic Overview</title>
<para>Written by Ove Kaaven</para>
<para>
Written by &name-ove-kaaven; <email>&email-ove-kaaven;</email>
</para>
<para>
With the fundamental architecture of Wine stabilizing, and
......@@ -1027,6 +1029,6 @@ WSOCK32.DLL: 32-bit sockets APIs
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-parent-document:("wine-doc.sgml" "book" "part" "chapter" "")
sgml-parent-document:("wine-doc.sgml" "set" "book" "part" "chapter" "")
End:
-->
<!-- *** List of author names
*** Allows us to maintain the list and change spam obfuscation
*** From a central location.
*** Use this template for new author attributions:
Written by &; <email>&;</email>
-->
<!-- ** Template for new entries **
<!entity name- "">
<!entity email- "">
-->
<!entity name-jonathan-buzzard "Jonathan Buzzard">
<!entity email-jonathan-buzzard "jab@hex.prestel.co.uk">
<!entity name-david-cuthbert "David A. Cuthbert">
<!entity email-david-cuthbert "dacut@ece.cmu.edu">
<!entity name-huw-davies "Huw D M Davies">
<!entity email-huw-davies "h.davies1@physics.ox.ac.uk">
<!entity name-steven-elliott "Steven Elliott">
<!entity email-steven-elliott "elliotsl@mindspring.com">
<!entity name-albert-den-haan "Albert den Haan">
<!entity email-albert-den-haan "">
<!entity name-james-juran "James Juran">
<!entity email-james-juran "juran@cse.psu.edu">
<!entity name-ove-kaaven "Ove Kven">
<!entity email-ove-kaaven "ovek@winehq.com">
<!entity name-eric-kohl "Eric Kohl">
<!entity email-eric-kohl "ekohl@abo.rhein-zeitung.de">
<!entity name-alex-korobka "Alex Korobka">
<!entity email-alex-korobka "alex@aikea.ams.sunysb.edu">
<!entity name-marcus-meissner "Marcus Meissner">
<!-- <!entity email-marcus-meissner "msmeissn@cip.informatik.uni-erlangen.de"> -->
<!entity email-marcus-meissner "Marcus.Meissner@caldera.de">
<!entity name-bruce-milner "Bruce Milner">
<!entity email-bruce-milner "">
<!entity name-andreas-mohr "Andreas Mohr">
<!-- <!entity email-andreas-mohr "a.mohr@mailto.de"> -->
<!entity email-andreas-mohr "amohr@codeweavers.com">
<!entity name-gerard-patel "Gerard Patel">
<!entity email-gerard-patel "">
<!entity name-dimitrie-paun "Dimitrie O. Paun">
<!entity email-dimitrie-paun "dimi@cs.toronto.edu">
<!entity name-eric-pouech "Eric Pouech">
<!entity email-eric-pouech "Eric.Pouech@wanadoo.fr">
<!entity name-robert-pouliot "Robert Pouliot">
<!entity email-robert-pouliot "krynos@clic.net">
<!entity name-joseph-pranevich "Joseph Pranevich">
<!entity email-joseph-pranevich "jpranevich@lycos.com">
<!entity name-alex-priem "Alex Priem">
<!entity email-alex-priem "alex@sci.kun.nl">
<!entity name-john-richardson "John Richardson">
<!entity email-john-richardson "jrichard@zko.dec.com">
<!entity name-douglas-ridgway "Douglas Ridgway">
<!entity email-douglas-ridgway "ridgway@winehq.com">
<!entity name-adam-sacarny "Adam Sacarny">
<!entity email-adam-sacarny "magicbox@bestweb.net">
<!entity name-juergen-schmied "Juergen Schmied">
<!entity email-juergen-schmied "juergen.schmied@metronet.de">
<!entity name-john-sheets "John R. Sheets">
<!entity email-john-sheets "jsheets@codeweavers.com">
<!entity name-petr-tomasek "Petr Tomasek">
<!entity email-petr-tomasek "tomasek@etf.cuni.cz">
<!entity name-lionel-ulmer "Lionel Ulmer">
<!entity email-lionel-ulmer "lionel.ulmer@free.fr">
<!entity name-morten-welinder "Morten Welinder">
<!entity email-morten-welinder "">
<!entity name-jeremy-white "Jeremy White">
<!entity email-jeremy-white "jwhite@codeweavers.com">
<!-- *** Coders mentioned in docs, but not doc writers *** -->
<!entity name-francis-beaudet "Francis Beaudet">
<!entity email-francis-beaudet "francis@macadamian.com">
<!entity name-anders-carlsson "Anders Carlsson">
<!entity email-anders-carlsson "anders.carlsson@linux.nu">
<!entity name-aric-stewart "Aric Stewart">
<!entity email-aric-stewart "aric@codeweavers.com">
<!entity name-luc-tourangeau "Luc Tourangeau">
<!entity email-luc-tourangeau "luc@macadamian.com">
<!entity name-koen-deforche "Koen Deforche">
<!entity email-koen-deforche "jozef@kotnet.org">
......@@ -5,7 +5,7 @@
<title>How To Report A Bug</title>
<para>
written by Gerard Patel (???)
Written by &name-gerard-patel; <email>&email-gerard-patel;</email>
</para>
<para>
(Extracted from <filename>wine/documentation/bugreports</filename>)
......@@ -25,14 +25,14 @@
<orderedlist>
<listitem>
<para>
Your computer *must* 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
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 *very* apparent if you don't have
perl.
script, it will become <emphasis>very</emphasis> apparent
if you don't have perl.
</para>
</listitem>
<listitem>
......@@ -130,7 +130,7 @@
<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 *only* <parameter>+relay</parameter>!! A bug
please use <emphasis>only</emphasis> <parameter>+relay</parameter>!! A bug
report with a crash in <parameter>+snoop</parameter>
code is useless in most cases!
</para>
......@@ -211,6 +211,6 @@
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-parent-document:("wine-doc.sgml" "book" "chapter" "")
sgml-parent-document:("wine-doc.sgml" "set" "book" "chapter" "")
End:
-->
......@@ -6,6 +6,6 @@
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-parent-document:("wine-doc.sgml" "book" "part" "chapter" "")
sgml-parent-document:("wine-doc.sgml" "set" "book" "part" "chapter" "")
End:
-->
<chapter id="compiling">
<title>Compiling Wine</title>
<para>How to compile wine, and problems that may arise...</para>
<sect1 id="compiling-wine">
<title>Compiling Wine</title>
<sect2>
<title>Tools required</title>
<para>
<itemizedlist>
<listitem>
<para>
gcc -- 2.7.x required (Wine uses attribute stdcall).
Versions earlier than 2.7.2.3 barf on shellord.c
-- compile without optimizing for that file.
In addition EGCS 1.1.x and GCC 2.95.x are reported
to work fine.
</para>
</listitem>
<listitem>
<para>
flex >= 2.5.1 (required for the debugger and wrc,
and lex won't do)
</para>
</listitem>
<listitem>
<para>
bison (also required for debugger. Don't know whether BSD yacc
would work.)
</para>
</listitem>
<listitem>
<para>
X11 libs and include files
</para>
</listitem>
<listitem>
<para>
Xpm libs and include files
</para>
</listitem>
<listitem>
<para>
texinfo >= 3.11 (optional, to compile the documentation.)
</para>
</listitem>
<listitem>
<para>
autoconf (if you want to remake configure, which is
not normally required)
</para>
</listitem>
<listitem>
<para>
XF86DGA extension (optional, detected by configure,
needed for DirectX support)
</para>
</listitem>
<listitem>
<para>
Open Sound System (optional, detected by configure,
for sound support)
</para>
</listitem>
</itemizedlist>
</para>
<para>
The Red Hat RPMs are gcc-XXX, flex-XXX, XFree86-devel-XXX, xpm-XXX,
and xpm-devel, where XXX is the version number.
</para>
</sect2>
<sect2>
<title>Space required</title>
<para>
You also need about 230 MB of available disk space for compilation.
The compiled libwine.so binary takes around 5 MB of disk space,
which can be reduced to about 1 MB by stripping ('strip wine').
Stripping is not recommended, however, as you can't submit
proper crash reports with a stripped binary any more.
</para>
</sect2>
<sect2>
<title>Common problems</title>
<para>
If you get a repeatable sig11 compiling shellord.c, thunk.c
or other files, try compiling just that file without optimization.
Then you should be able to finish the build.
</para>
</sect2>
<sect2>
<title>OS specific issues</title>
<para>
<itemizedlist>
<listitem>
<para>
FreeBSD -- In order to run Wine, the FreeBSD kernel
needs to be compiled with
<informaltable frame="all">
<tgroup cols="2">
<tbody>
<row>
<entry>options</entry>
<entry>USER_LDT</entry>
</row>
<row>
<entry>options</entry>
<entry>SYSVSHM</entry>
</row>
<row>
<entry>options</entry>
<entry>SYSVSEM</entry>
</row>
<row>
<entry>options</entry>
<entry>SYSVMSG</entry>
</row>
</tbody>
</tgroup>
</informaltable>
If you need help, read the chapter "<ulink url="http://www.freebsd.org/handbook/kernelconfig-building.html">Building and Installing a Custom Kernel</ulink>" in the "<ulink url="http://www.freebsd.org/handbook/">FreeBSD handbook</ulink>. You'll need to be running FreeBSD 3.x or later.
</para>
</listitem>
<listitem>
<para>
SCO Unixware, Openserver -- UW port is supported by SCO.
</para>
</listitem>
<listitem>
<para>
OS/2 -- not a complete port. See <ulink url="http://odin.netlabs.org/ProjectAbout.phtml">Odin</ulink> for a project which uses some Wine code.
</para>
</listitem>
<listitem>
<para>
Solaris x86 2.x -- Needs GNU toolchain (gcc, gas, flex as above, yacc may work) to compile, seems functional (980215).
</para>
</listitem>
<listitem>
<para>
DGUX, HP, Irix, or other Unixes; non-intel Linux.
No ports have been seriously attempted.
For non-intel Unixes, only a winelib port is relevant.
Alignment may be a problem.
</para>
</listitem>
<listitem>
<para>
Macintosh/Rhapsody/BeOS -- no ports have been attempted.
</para>
</listitem>
</itemizedlist>
</para>
</sect2>
</sect1>
</chapter>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-parent-document:("wine-doc.sgml" "book" "part" "chapter" "")
sgml-parent-document:("wine-doc.sgml" "set" "book" "part" "chapter" "")
End:
-->
......@@ -5,7 +5,7 @@
<sect1 id="config">
<title>General Configuration</title>
<para>
Copyright 1999 Adam Sacarny (magicbox@bestweb.net)
Copyright 1999 &name-adam-sacarny; <email>&email-adam-sacarny;</email>
</para>
<para>
(Extracted from <filename>wine/documentation/config</filename>)
......@@ -515,7 +515,7 @@ winsock = wsock32
</programlisting>
</para>
<para>
For example, to load builtin KERNEL pair (Case doesn't
For example, to load builtin KERNEL pair (case doesn't
matter here):
<programlisting>
kernel,kernel32 = builtin
......@@ -649,7 +649,7 @@ Alias1 = Foo,--google-,subst
<title>The [serialports], [parallelports], [spooler], and [ports] Sections</title>
<para>
Even though it sounds like a lot of sections, these are
all closely related. They all are for communications and
all closely related. They are all for communications and
parallel ports.
</para>
<para>
......@@ -678,7 +678,7 @@ Alias1 = Foo,--google-,subst
<programlisting>LptX=/dev/lpY</programlisting>
</para>
<para>
Seem farmiliar? Syntax is just like the COM port setting.
Sounds familiar? Syntax is just like the COM port setting.
Replace <literal>X</literal> with a value from 1-4 as it
is in Windows and <literal>Y</literal> with a value from
0-3 (<literal>Y</literal> is usually the value in windows
......@@ -714,7 +714,7 @@ Alias1 = Foo,--google-,subst
</para>
<para>
<programlisting>write=0x779,0x379,0x280-0x2a0</programlisting>
Gives direct write access to those IO's. It probably a
Gives direct write access to those IO's. It's probably a
good idea to keep the values of the
<literal>read</literal> and <literal>write</literal>
settings the same. This stuff will only work when you're
......@@ -725,7 +725,7 @@ Alias1 = Foo,--google-,subst
<sect3>
<title>The [spy], [Registry], [tweak.layout], and [programs] Sections</title>
<para>
[spy] is used to Include or exclude debug messages, and to
[spy] is used to include or exclude debug messages, and to
output them to a file. The latter is rarely used. THESE
ARE ALL OPTIONAL AND YOU PROBABLY DON'T NEED TO ADD OR
REMOVE ANYTHING IN THIS SECTION TO YOUR CONFIG.
......@@ -816,20 +816,19 @@ Alias1 = Foo,--google-,subst
<para>
There is always a chance that things will go wrong. If the
unthinkable happens, try the newsgroup,
<systemitem>comp.emulators.ms-windows.wine</systemitem> Make sure that you have
looked over this document thoroughly, and have also read:
<systemitem>comp.emulators.ms-windows.wine</systemitem>,
or the IRCnet channel <systemitem>#WineHQ</systemitem>.
Make sure that you have looked over this document thoroughly,
and have also read:
</para>
<itemizedlist>
<listitem>
<para><filename>README</filename></para>
</listitem>
<listitem>
<para><filename>documentation/bugreports</filename></para>
</listitem>
<listitem>
<para>
<filename>http://www.westfalen.de/witch/wine-HOWTO.txt</filename>
(Optional but recommended)
<filename>http://www.la-sorciere.de/wine/index.html</filename>
(optional but recommended)
</para>
</listitem>
</itemizedlist>
......@@ -844,7 +843,7 @@ Alias1 = Foo,--google-,subst
<sect1 id="win95look">
<title>Win95/98 Look</title>
<para>
by ???
Written by &name-david-cuthbert; <email>&email-david-cuthbert;</email>
</para>
<para>
(Extracted from <filename>wine/documentation/win95look</filename>)
......@@ -887,10 +886,10 @@ WineLook=[Win31|Win95|Win98] # Changes Wine's look and feel
<title>Configuring the x11drv Driver</title>
<para>
written by Ove Kåven
Written by &name-ove-kaaven; <email>&email-ove-kaaven;</email>
</para>
<para>
(Extracted from <filename>wine/documentation/x11drv</filename>)
(Extracted from <filename>wine/documentation/cdrom-labels</filename>)
</para>
<para>
......@@ -1136,7 +1135,7 @@ WineLook=[Win31|Win95|Win98] # Changes Wine's look and feel
<firstname>Petr</firstname>
<surname>Tomasek</surname>
<affiliation>
<address><email>&lt;tomasek@etf.cuni.cz></email></address>
<address><email>&email-petr-tomasek;</email></address>
</affiliation>
<contrib>Nov 14 1999</contrib>
</author>
......@@ -1144,7 +1143,7 @@ WineLook=[Win31|Win95|Win98] # Changes Wine's look and feel
<firstname>Andreas</firstname>
<surname>Mohr</surname>
<affiliation>
<address><email>&lt;a.mohr@mailto.de></email></address>
<address><email>&email-andreas-mohr;</email></address>
</affiliation>
<contrib>Jan 25 2000</contrib>
</author>
......@@ -1153,11 +1152,11 @@ WineLook=[Win31|Win95|Win98] # Changes Wine's look and feel
<title>Drive labels and serial numbers with wine</title>
<para>
by Petr Tomasek &lt;tomasek@etf.cuni.cz>
Written by &name-petr-tomasek; <email>&email-petr-tomasek;</email>
Nov 14 1999
</para>
<para>
changes by Andreas Mohr &lt;a.mohr@mailto.de>
Changes by &name-andreas-mohr; <email>&email-andreas-mohr;</email>
Jan 25 2000
</para>
<para>
......@@ -1221,9 +1220,9 @@ WineLook=[Win31|Win95|Win98] # Changes Wine's look and feel
</para>
<para>
If you want to give a <literal>Device=</literal> entry
*only* for drive raw sector accesses, but not for reading
the volume info from the device (i.e. you want a
<emphasis>fixed</emphasis>, preconfigured label), you need
<emphasis>only</emphasis> for drive raw sector accesses,
but not for reading the volume info from the device (i.e. you want
a <emphasis>fixed</emphasis>, preconfigured label), you need
to specify <literal>ReadVolInfo=0</literal> to tell Wine to
skip the volume reading.
</para>
......@@ -1292,7 +1291,9 @@ Filesystem=msdos
<sect1 id="dll-overrides">
<title>Dll Overrides</title>
<para>by Ove Kaaven &lt;ovek@arcticnet.no></para>
<para>
Written by &name-ove-kaaven; <email>&email-ove-kaaven;</email>
</para>
<para>
(Extracted from <filename>wine/documentation/dll-overrides</filename>)
</para>
......@@ -1350,7 +1351,7 @@ Filesystem=msdos
A native Unix <filename>.so</filename> file, with
calling convention conversion thunks generated on the
fly as the library is loaded. This is mostly useful
for libraries such as "glide" that has exactly the
for libraries such as "glide" that have exactly the
same API on both Windows and Unix.
</para> </listitem>
</varlistentry>
......@@ -1690,7 +1691,9 @@ Filesystem=msdos
<sect1 id="keyboard">
<title>Keyboard</title>
<para>by Ove Kaaven &lt;ovek@arcticnet.no></para>
<para>
Written by &name-ove-kaaven; <email>&email-ove-kaaven;</email>
</para>
<para>
(Extracted from <filename>wine/documentation/keyboard</filename>)
</para>
......@@ -1869,6 +1872,6 @@ diff -u the_backup_file_you_made windows/x11drv/keyboard.c > layout.diff
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-parent-document:("wine-doc.sgml" "book" "chapter" "")
sgml-parent-document:("wine-doc.sgml" "set" "book" "chapter" "")
End:
-->
......@@ -5,7 +5,8 @@
<title>Consoles</title>
<para>
written by (???)
Written by &name-john-richardson; <email>&email-john-richardson;</email>
Maintained by &name-joseph-pranevich; <email>&email-joseph-pranevich;</email>
</para>
<para>
(Extracted from <filename>wine/documentation/console</filename>)
......@@ -19,7 +20,7 @@
<parameter>-Sxxn</parameter> switch. A
<systemitem>pty</systemitem> is opened and the master goes
to the <filename>xterm</filename> side and the slave is held
by the wine side. The console itself it turned into a few
by the wine side. The console itself is turned into a few
<type>HANDLE32</type>s and is set to the
<varname>STD_*_HANDLES</varname>.
</para>
......@@ -35,7 +36,7 @@
</para>
<para>
<emphasis>[this paragraph is now out of date]</emphasis> If
the command line console is to be inheirited or a process
the command line console is to be inherited or a process
inherits its parent's console (-- can that happen???), the
console is created at process init time via
<function>PROCESS_InheritConsole</function>. The
......@@ -90,7 +91,7 @@
processing input. Win32 has line-at-a-time processing,
character processing, and echo. I'm putting together an
intermediate driver that will handle this (and hopefully
won't be any more buggy then the NT4 console
won't be any more buggy than the NT4 console
implementation).
</para>
</sect2>
......@@ -297,7 +298,7 @@ wine -console ncurses+xterm &lt;application&gt;
<para>
Tell any driver that is interested (ncurses) which
termcap and/or terminfo type to use. The default is
xterm which is appropiate for most uses.
xterm which is appropriate for most uses.
<command>nxterm</command> may give you better
support if you use that terminal. This can also be
changed to "linux" (or "console" on older systems)
......@@ -381,6 +382,6 @@ wine -console ncurses+xterm &lt;application&gt;
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-parent-document:("wine-doc.sgml" "book" "part" "chapter" "")
sgml-parent-document:("wine-doc.sgml" "set" "book" "part" "chapter" "")
End:
-->
<chapter id="cvs-regression">
<title>How to do regression testing using Cvs</title>
<para>
written by (???)
</para>
<para>
(Extracted from <filename>wine/documentation/bugreports</filename>)
</para>
<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 occured. This is
<emphasis>NOT</emphasis> for casual users.
</para>
<orderedlist>
<listitem>
<para>
Get the 'full cvs' archive from winehq. This archive is
the cvs tree but with the tags controlling the versioning
system. It's a big file (> 15 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 -zxffull-cvs-2000-05-20.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
cd /home/gerard
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>
</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 -d $CVSROOT update -D "1999-06-01"
</screen>
</para>
<para>
The date format is <literal>YYYY-MM-DD</literal>.
</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>
When you have found the exact date when a bug was added to
the cvs tree, use something like :
<screen>
cvs -d $CVSROOT diff -D "1999-07-10" -D "1999-07-12"
</screen>
to get all the differences between the last cvs tree
version known to work and code that first displayed the
misbehavior.
</para>
<note>
<para>
I did not include flags for <command>diff</command>
since they are in my <filename>.cvsrc</filename> file:
</para>
<screen>
cvs -z 3
update -dPA
diff -u
</screen>
</note>
<para>
From this diff file, particularly the file names, and the
<filename>ChangeLog</filename>, it's usually possible to
find the different individual patches that were done at
this time.
</para>
<para>
If any non-programmer reads this, the fastest method to get
at the point where the problem occured is to use a binary
search, that is, if the problem occured 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>
</listitem>
<listitem>
<para>
The next step is to start from the last working version
and to dig the individual contributions from
<ulink url="http://www.integrita.com/cgi-local/lwgate.pl/WINE-PATCHES/">
http://www.integrita.com/cgi-local/lwgate.pl/WINE-PATCHES/</ulink>
(where the Wine patches mailing list is archived)
</para>
<para>
If the patch was done by the Wine maintainer or if it was
sent directly to his mail address without going first through
<ulink url="mailto:wine-patches@winehq.com">wine-patches</ulink>,
you are out of luck as you will never find the patch in
the archive. If it is, it's often possible to apply the
patches one by one to last working cvs snapshot, compile and test.
If you have saved the next candidate as
<filename>/home/gerard/buggedpatch1.txt</filename>:
</para>
<screen>
cd /home/gerard/wine
patch -p 0 &lt; /home/gerard/buggedpatch1.txt
</screen>
<para>
Beware that the committed patch is not always identical to
the patch that the author sent to wine-patches, as
sometimes the Wine maintainer changes things a bit.
</para>
<para>
If you find one patch that is getting the cvs source tree to
reproduce the problem, you have almost won; post the problem on
<systemitem>comp.emulators.windows.wine</systemitem> and 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>
</chapter>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-parent-document:("wine-doc.sgml" "set" "book" "part" "chapter" "")
End:
-->
#! /bin/sh
## Customized version of db2html to make it easier to use alternate
## stylesheets. Some versions of db2html support a '-d' option to
## specify this, but not all. We'll explicitly specify that here.
##
## John R. Sheets <jsheets@codeweavers.com>
## Other possible SGML stylesheets (default Debian versions...may be
## different on other distributions).
#DB_STYLESHEET=/usr/lib/sgml/stylesheet/dsssl/docbook/cygnus/cygnus-both.dsl
#DB_STYLESHEET=/usr/lib/sgml/stylesheet/dsssl/docbook/nwalsh/html/docbook.dsl
## Use included default.dsl DSSSL stylesheet unless explicitly overridden with
## the $WINEDOC_STYLESHEET envar.
##
## NOTE: The invoked DSSSL stylesheet *MUST* have an HTML-specific section
## in it; otherwise, jade will spew everything to stdout and fail to use
## the stated stylesheet. Something like this:
##
## <style-specification id="html" use="docbook">
if [ -z "$WINEDOC_STYLESHEET" ]; then
DB_STYLESHEET=../default.dsl
else
DB_STYLESHEET=$WINEDOC_STYLESHEET
fi
output=db2html-dir
TMPDIR=DBTOHTML_OUTPUT_DIR$$
echo TMPDIR is $TMPDIR
echo "Using stylesheet: \"${DB_STYLESHEET}\""
if [ $# -gt 2 ]
then
echo "Usage: `basename $0` [filename.sgml]" >&2
exit 1
fi
if [ $# -eq 1 ]
then
if [ ! -r $1 ]
then
echo Cannot read \"$1\". Exiting. >&2
exit 1
fi
if echo $1 | egrep -i '\.sgml$|\.sgm$' >/dev/null 2>&1
then
# now make sure that the output directory is always a subdirectory
# of the current directory
echo
input_file=`basename $1`
output="`echo $input_file | sed 's,\.sgml$,,;s,\.sgm$,,'`"
echo "input file was called $input_file -- output will be in $output"
echo
fi
fi
mkdir $TMPDIR
SAVE_PWD=`pwd`
if [ $1 = `basename $1` ]; then
echo "working on ../$1"
(cd $TMPDIR; jade -t sgml -ihtml -d ${DB_STYLESHEET}\#html ../$1; cd $SAVE_PWD)
else
echo "working on $1"
(cd $TMPDIR; jade -t sgml -ihtml -d ${DB_STYLESHEET}\#html $1; cd $SAVE_PWD)
fi
if [ $# -eq 1 ]
then
if [ -d ${output}.junk ]
then
/bin/rm -rf ${output}.junk
fi
if [ -d ${output} ]
then
mv $output ${output}.junk
fi
echo "about to rename temporary directory to $output"
mv ${TMPDIR} $output
else
cat $TMPDIR/*
fi
rm -rf $TMPDIR
exit 0
<chapter id="debugger">
<title>The Wine Debugger</title>
<title>Debugging Wine</title>
<sect1 id="dbg-intro">
<title>I Introduction</title>
<title>Introduction</title>
<para>
written by Eric Pouech (Last updated: 8/15/2000)
Written by &name-eric-pouech; <email>&email-eric-pouech;</email>
(Last updated: 6/14/2000)
</para>
<para>
(Extracted from <filename>wine/documentation/winedbg</filename>)
</para>
<sect2>
<title>I.1 Processes and threads: in underlying OS and in Windows</title>
<title>Processes and threads: in underlying OS and in Windows</title>
<para>
Before going into the depths of debugging in Wine, here's
......@@ -80,7 +81,7 @@
</sect2>
<sect2>
<title>I.2 Wine, debugging and WineDbg</title>
<title>Wine, debugging and WineDbg</title>
<para>
When talking of debugging in Wine, there are at least two
......@@ -96,35 +97,30 @@
</listitem>
</itemizedlist>
<para>
Wine implements most the the Windows' debugging API (the
Wine implements most of the Windows' debugging API (the
part in KERNEL32, not the one in
<filename>IMAGEHLP.DLL</filename>), and allows any program
(emulated or WineLib) using that API to debug a
(emulated or Winelib) using that API to debug a
<varname>W-process</varname>.
</para>
<para>
<command>WineDbg</command> is a WineLib application making
use of this API to allow debugging both any Wine or WineLib
<command>WineDbg</command> is a Winelib application making
use of this API to allow debugging both any Wine or Winelib
applications as well as Wine itself (kernel and all DLLs).
</para>
<para>
<command>WineDbg</command> understands symbolic information
from both Unix world (mainly ELF stabs) and from Windows
(most Microsoft debugging formats are supported - CodeView,
.DBG files...)
</para>
</sect2>
</sect1>
<sect1 id="dbg-modes">
<title>II WineDbg's modes of invocation</title>
<title>WineDbg's modes of invocation</title>
<sect2>
<title>II.1 Starting a process</title>
<title>Starting a process</title>
<para>
Any application (either a Windows' native executable, or a
WineLib application) can be run through
Winelib application) can be run through
<command>WineDbg</command>. Command line options and tricks
are the same as for wine:
</para>
......@@ -135,7 +131,7 @@ winedbg "hl.exe -windowed"
</sect2>
<sect2>
<title>II.2 Attaching</title>
<title>Attaching</title>
<para>
<command>WineDbg</command> can also be launched without any
......@@ -156,8 +152,8 @@ winedbg "hl.exe -windowed"
</itemizedlist>
</sect2>
<sect2>
<title>II.3 On exception</title>
<sect2 id="dbg-on-exception">
<title id="dbg-exception-title">On exception</title>
<para>
When something goes wrong, Windows tracks this as an
......@@ -237,7 +233,7 @@ winedbg "hl.exe -windowed"
</sect2>
<sect2>
<title>II.4 Quitting</title>
<title>Quitting</title>
<para>
Unfortunately, Windows doesn't provide a detach kind of API,
......@@ -250,16 +246,703 @@ winedbg "hl.exe -windowed"
</sect2>
</sect1>
<sect1 id="wine-debugger">
<title>Using the Wine Debugger</title>
<para>
Written by &name-marcus-meissner; <email>&email-marcus-meissner;</email>,
additions welcome.
</para>
<para>
(Extracted from <filename>wine/documentation/debugging</filename>)
</para>
<para>
This file describes where to start debugging Wine. If at any
point you get stuck and want to ask for help, please read the
file <filename>documentation/bugreports</filename> for
information on how to write useful bug reports.
</para>
<sect2>
<title>Crashes</title>
<para>
These usually show up like this:
</para>
<screen>
|Unexpected Windows program segfault - opcode = 8b
|Segmentation fault in Windows program 1b7:c41.
|Loading symbols from ELF file /root/wine/wine...
|....more Loading symbols from ...
|In 16 bit mode.
|Register dump:
| CS:01b7 SS:016f DS:0287 ES:0000
| IP:0c41 SP:878a BP:8796 FLAGS:0246
| AX:811e BX:0000 CX:0000 DX:0000 SI:0001 DI:ffff
|Stack dump:
|0x016f:0x878a: 0001 016f ffed 0000 0000 0287 890b 1e5b
|0x016f:0x879a: 01b7 0001 000d 1050 08b7 016f 0001 000d
|0x016f:0x87aa: 000a 0003 0004 0000 0007 0007 0190 0000
|0x016f:0x87ba:
|
|0050: sel=0287 base=40211d30 limit=0b93f (bytes) 16-bit rw-
|Backtrace:
|0 0x01b7:0x0c41 (PXSRV_FONGETFACENAME+0x7c)
|1 0x01b7:0x1e5b (PXSRV_FONPUTCATFONT+0x2cd)
|2 0x01a7:0x05aa
|3 0x01b7:0x0768 (PXSRV_FONINITFONTS+0x81)
|4 0x014f:0x03ed (PDOXWIN_@SQLCURCB$Q6CBTYPEULN8CBSCTYPE+0x1b1)
|5 0x013f:0x00ac
|
|0x01b7:0x0c41 (PXSRV_FONGETFACENAME+0x7c): movw %es:0x38(%bx),%dx
</screen>
<para>
Steps to debug a crash. You may stop at any step, but please
report the bug and provide as much of the information
gathered to the newsgroup or the relevant developer as
feasible.
</para>
<orderedlist>
<listitem>
<para>
Get the reason for the crash. This is usually an access to
an invalid selector, an access to an out of range address
in a valid selector, popping a segmentregister from the
stack or the like. When reporting a crash, report this
<emphasis>whole</emphasis> crashdump even if it doesn't
make sense to you.
</para>
<para>
(In this case it is access to an invalid selector, for
<systemitem>%es</systemitem> is <literal>0000</literal>, as
seen in the register dump).
</para>
</listitem>
<listitem>
<para>
Determine the cause of the crash. Since this is usually
a primary/secondary reaction to a failed or misbehaving
Wine function, rerun Wine with <parameter>-debugmsg
+relay</parameter> added to the commandline. This will
generate quite a lot of output, but usually the reason is
located in the last call(s). Those lines usually look like
this:
</para>
<screen>
|Call KERNEL.90: LSTRLEN(0227:0692 "text") ret=01e7:2ce7 ds=0227
^^^^^^^^^ ^ ^^^^^^^^^ ^^^^^^ ^^^^^^^^^ ^^^^
| | | | | |Datasegment
| | | | |Return address
| | | |textual parameter
| | |
| | |Argument(s). This one is a win16 segmented pointer.
| |Function called.
|The module, the function is called in. In this case it is KERNEL.
|Ret KERNEL.90: LSTRLEN() retval=0x0004 ret=01e7:2ce7 ds=0227
^^^^^^
|Returnvalue is 16 bit and has the value 4.
</screen>
</listitem>
<listitem>
<para>
If you have found a misbehaving function, try to find out
why it misbehaves. Find the function in the source code.
Try to make sense of the arguments passed. Usually there is
a <function>TRACE(&lt;channel>,"(...)\n");</function> at
the beginning of the function. Rerun wine with
<parameter>-debugmsg +xyz,+relay</parameter> added to the
commandline.
</para>
</listitem>
<listitem>
<para>
Additional information on how to debug using the internal
debugger can be found in
<filename>debugger/README</filename>.
</para>
</listitem>
<listitem>
<para>
If this information isn't clear enough or if you want to
know more about what's happening in the function itself,
try running wine with <parameter>-debugmsg
+all</parameter>, which dumps ALL included debug
information in wine.
</para>
</listitem>
<listitem>
<para>
If even that isn't enough, add more debug output for
yourself into the functions you find relevant. See
<filename>documentation/debug-msgs</filename>. You might
also try to run the program in <command>gdb</command>
instead of using the WINE-debugger. If you do that, use
<parameter>handle SIGSEGV nostop noprint</parameter> to
disable the handling of seg faults inside
<command>gdb</command> (needed for Win16). If you don't use
the <parameter>--desktop</parameter> or
<parameter>--managed</parameter> option, start the WINE
process with <parameter>--sync</parameter>, or chances are
good to get X into an unusable state.
</para>
</listitem>
<listitem>
<para>
You can also set a breakpoint for that function. Start wine
with the <parameter>--debug</parameter> option added to the
commandline. After loading the executable wine will enter
the internal debugger. Use <parameter>break
KERNEL_LSTRLEN</parameter> (replace by function you want
to debug, CASE IS RELEVANT) to set a breakpoint. Then use
<command>continue</command> to start normal
program-execution. Wine will stop if it reaches the
breakpoint. If the program isn't yet at the crashing call
of that function, use <command>continue</command> again
until you are about to enter that function. You may now
proceed with single-stepping the function until you reach
the point of crash. Use the other debugger commands to
print registers and the like.
</para>
</listitem>
</orderedlist>
</sect2>
<sect2>
<title>Program hangs, nothing happens</title>
<para>
Switch to UNIX shell, get the process-ID using <command>ps -a |
grep wine</command>, and do a <command>kill -HUP
&lt;pid></command> (without the &lt; and >). Wine will
then enter its internal debugger and you can proceed as
explained above. Also, you can use
<parameter>--debug</parameter> switch and then you can get into
internal debugger by pressing
<keycombo><keycap>Ctrl</keycap><keycap>C</keycap></keycombo> in
the terminal where you run Wine.
</para>
</sect2>
<sect2>
<title>Program reports an error with a Messagebox</title>
<para>
Sometimes programs are reporting failure using more or
less nondescript messageboxes. We can debug this using the
same method as Crashes, but there is one problem... For
setting up a message box the program also calls Wine
producing huge chunks of debug code.
</para>
<para>
Since the failure happens usually directly before setting up
the Messagebox you can start wine with
<parameter>--debug</parameter> added to the commandline, set a
breakpoint at <function>MessageBoxA</function> (called by win16
and win32 programs) and proceed with
<command>continue</command>. With <parameter>--debugmsg
+all</parameter> Wine will now stop directly before setting
up the Messagebox. Proceed as explained above.
</para>
<para>
You can also run wine using <command>wine -debugmsg +relay
program.exe 2>&1 | less -i</command> and in
<command>less</command> search for <quote>MessageBox</quote>.
</para>
</sect2>
<sect2>
<title>Disassembling programs:</title>
<para>
You may also try to disassemble the offending program to
check for undocumented features and/or use of them.
</para>
<para>
The best, freely available, disassembler for Win16 programs is
<application>Windows Codeback</application>, archivename
<filename>wcbxxx.zip</filename>, which usually can be found in
the <filename>Cica-Mirror</filename> subdirectory on the WINE
ftpsites. (See <filename>ANNOUNCE</filename>).
</para>
<para>
Disassembling win32 programs is possible using
<application>Windows Disassembler 32</application>, archivename
something like <filename>w32dsm87.zip</filename> (or similar)
on <systemitem class="systemname">ftp.winsite.com</systemitem>
and mirrors. The shareware version does not allow saving of
disassembly listings. You can also use the newer (and in the
full version better) <application>Interactive
Disassembler</application> (IDA) from the ftp sites mentioned
at the end of the document. Understanding disassembled code is
mostly a question of exercise.
</para>
<para>
Most code out there uses standard C function entries (for it
is usually written in C). Win16 function entries usually
look like that:
</para>
<programlisting>
push bp
mov bp, sp
... function code ..
retf XXXX &lt;--------- XXXX is number of bytes of arguments
</programlisting>
<para>
This is a <function>FAR</function> function with no local
storage. The arguments usually start at
<literal>[bp+6]</literal> with increasing offsets. Note, that
<literal>[bp+6]</literal> belongs to the
<emphasis>rightmost</emphasis> argument, for exported win16
functions use the PASCAL calling convention. So, if we use
<function>strcmp(a,b)</function> with <parameter>a</parameter>
and <parameter>b</parameter> both 32 bit variables
<parameter>b</parameter> would be at <literal>[bp+6]</literal>
and <parameter>a</parameter> at <literal>[bp+10]</literal>.
</para>
<para>
Most functions make also use of local storage in the stackframe:
</para>
<programlisting>
enter 0086, 00
... function code ...
leave
retf XXXX
</programlisting>
<para>
This does mostly the same as above, but also adds
<literal>0x86</literal> bytes of stackstorage, which is
accessed using <literal>[bp-xx]</literal>. Before calling a
function, arguments are pushed on the stack using something
like this:
</para>
<programlisting>
push word ptr [bp-02] &lt;- will be at [bp+8]
push di &lt;- will be at [bp+6]
call KERNEL.LSTRLEN
</programlisting>
<para>
Here first the selector and then the offset to the passed
string are pushed.
</para>
</sect2>
<sect2>
<title>Sample debugging session:</title>
<para>
Let's debug the infamous Word <filename>SHARE.EXE</filename>
messagebox:
</para>
<screen>
|marcus@jet $ wine winword.exe
| +---------------------------------------------+
| | ! You must leave Windows and load SHARE.EXE|
| | before starting Word. |
| +---------------------------------------------+
</screen>
<screen>
|marcus@jet $ wine winword.exe -debugmsg +relay -debug
|CallTo32(wndproc=0x40065bc0,hwnd=000001ac,msg=00000081,wp=00000000,lp=00000000)
|Win16 task 'winword': Breakpoint 1 at 0x01d7:0x001a
|CallTo16(func=0127:0070,ds=0927)
|Call WPROCS.24: TASK_RESCHEDULE() ret=00b7:1456 ds=0927
|Ret WPROCS.24: TASK_RESCHEDULE() retval=0x8672 ret=00b7:1456 ds=0927
|CallTo16(func=01d7:001a,ds=0927)
| AX=0000 BX=3cb4 CX=1f40 DX=0000 SI=0000 DI=0927 BP=0000 ES=11f7
|Loading symbols: /home/marcus/wine/wine...
|Stopped on breakpoint 1 at 0x01d7:0x001a
|In 16 bit mode.
|Wine-dbg>break MessageBoxA &lt;---- Set Breakpoint
|Breakpoint 2 at 0x40189100 (MessageBoxA [msgbox.c:190])
|Wine-dbg>c &lt;---- Continue
|Call KERNEL.91: INITTASK() ret=0157:0022 ds=08a7
| AX=0000 BX=3cb4 CX=1f40 DX=0000 SI=0000 DI=08a7 ES=11d7 EFL=00000286
|CallTo16(func=090f:085c,ds=0dcf,0x0000,0x0000,0x0000,0x0000,0x0800,0x0000,0x0000,0x0dcf)
|... &lt;----- Much debugoutput
|Call KERNEL.136: GETDRIVETYPE(0x0000) ret=060f:097b ds=0927
^^^^^^ Drive 0 (A:)
|Ret KERNEL.136: GETDRIVETYPE() retval=0x0002 ret=060f:097b ds=0927
^^^^^^ DRIVE_REMOVEABLE
(It is a floppy diskdrive.)
|Call KERNEL.136: GETDRIVETYPE(0x0001) ret=060f:097b ds=0927
^^^^^^ Drive 1 (B:)
|Ret KERNEL.136: GETDRIVETYPE() retval=0x0000 ret=060f:097b ds=0927
^^^^^^ DRIVE_CANNOTDETERMINE
(I don't have drive B: assigned)
|Call KERNEL.136: GETDRIVETYPE(0x0002) ret=060f:097b ds=0927
^^^^^^^ Drive 2 (C:)
|Ret KERNEL.136: GETDRIVETYPE() retval=0x0003 ret=060f:097b ds=0927
^^^^^^ DRIVE_FIXED
(specified as a harddisk)
|Call KERNEL.97: GETTEMPFILENAME(0x00c3,0x09278364"doc",0x0000,0927:8248) ret=060f:09b1 ds=0927
^^^^^^ ^^^^^ ^^^^^^^^^
| | |buffer for fname
| |temporary name ~docXXXX.tmp
|Force use of Drive C:.
|Warning: GetTempFileName returns 'C:~doc9281.tmp', which doesn't seem to be writeable.
|Please check your configuration file if this generates a failure.
</screen>
<para>
Whoops, it even detects that something is wrong!
</para>
<screen>
|Ret KERNEL.97: GETTEMPFILENAME() retval=0x9281 ret=060f:09b1 ds=0927
^^^^^^ Temporary storage ID
|Call KERNEL.74: OPENFILE(0x09278248"C:~doc9281.tmp",0927:82da,0x1012) ret=060f:09d8 ds=0927
^^^^^^^^^^^^^^^^ ^^^^^^^^^ ^^^^^^^
|filename |OFSTRUCT |open mode:
OF_CREATE|OF_SHARE_EXCLUSIVE|OF_READWRITE
</screen>
<para>
This fails, since my <medialabel>C:</medialabel> drive is in
this case mounted readonly.
</para>
<screen>
|Ret KERNEL.74: OPENFILE() retval=0xffff ret=060f:09d8 ds=0927
^^^^^^ HFILE_ERROR16, yes, it failed.
|Call USER.1: MESSAGEBOX(0x0000,0x09278376"Sie mussen Windows verlassen und SHARE.EXE laden bevor Sie Word starten.",0x00000000,0x1030) ret=060f:084f ds=0927
</screen>
<para>
And MessageBox'ed.
</para>
<screen>
|Stopped on breakpoint 2 at 0x40189100 (MessageBoxA [msgbox.c:190])
|190 { &lt;- the sourceline
In 32 bit mode.
Wine-dbg>
</screen>
<para>
The code seems to find a writeable harddisk and tries to create
a file there. To work around this bug, you can define
<medialabel>C:</medialabel> as a networkdrive, which is ignored
by the code above.
</para>
</sect2>
<sect2>
<title>Debugging Tips</title>
<para>
Here are some useful debugging tips, added by Andreas Mohr:
</para>
<itemizedlist>
<listitem>
<para>
If you have a program crashing at such an early loader phase that you can't
use the Wine debugger normally, but Wine already executes the program's
start code, then you may use a special trick. You should do a
<programlisting>
wine --debugmsg +relay program
</programlisting>
to get a listing of the functions the program calls in its start function.
Now you do a
<programlisting>
wine --debug winfile.exe
</programlisting>
</para>
<para>
This way, you get into <command>Wine-dbg</command>. Now you
can set a breakpoint on any function the program calls in
the start function and just type <userinput>c</userinput>
to bypass the eventual calls of Winfile to this function
until you are finally at the place where this function gets
called by the crashing start function. Now you can proceed
with your debugging as usual.
</para>
</listitem>
<listitem>
<para>
If you try to run a program and it quits after showing an error messagebox,
the problem can usually be identified in the return value of one of the
functions executed before <function>MessageBox()</function>.
That's why you should re-run the program with e.g.
<programlisting>
wine --debugmsg +relay &lt;program name> &>relmsg
</programlisting>
Then do a <command>more relmsg</command> and search for the
last occurrence of a call to the string "MESSAGEBOX". This is a line like
<programlisting>
Call USER.1: MESSAGEBOX(0x0000,0x01ff1246 "Runtime error 219 at 0004:1056.",0x00000000,0x1010) ret=01f7:2160 ds=01ff
</programlisting>
In my example the lines before the call to
<function>MessageBox()</function> look like that:
<programlisting>
Call KERNEL.96: FREELIBRARY(0x0347) ret=01cf:1033 ds=01ff
CallTo16(func=033f:0072,ds=01ff,0x0000)
Ret KERNEL.96: FREELIBRARY() retval=0x0001 ret=01cf:1033 ds=01ff
Call KERNEL.96: FREELIBRARY(0x036f) ret=01cf:1043 ds=01ff
CallTo16(func=0367:0072,ds=01ff,0x0000)
Ret KERNEL.96: FREELIBRARY() retval=0x0001 ret=01cf:1043 ds=01ff
Call KERNEL.96: FREELIBRARY(0x031f) ret=01cf:105c ds=01ff
CallTo16(func=0317:0072,ds=01ff,0x0000)
Ret KERNEL.96: FREELIBRARY() retval=0x0001 ret=01cf:105c ds=01ff
Call USER.171: WINHELP(0x02ac,0x01ff05b4 "COMET.HLP",0x0002,0x00000000) ret=01cf:1070 ds=01ff
CallTo16(func=0117:0080,ds=01ff)
Call WPROCS.24: TASK_RESCHEDULE() ret=00a7:0a2d ds=002b
Ret WPROCS.24: TASK_RESCHEDULE() retval=0x0000 ret=00a7:0a2d ds=002b
Ret USER.171: WINHELP() retval=0x0001 ret=01cf:1070 ds=01ff
Call KERNEL.96: FREELIBRARY(0x01be) ret=01df:3e29 ds=01ff
Ret KERNEL.96: FREELIBRARY() retval=0x0000 ret=01df:3e29 ds=01ff
Call KERNEL.52: FREEPROCINSTANCE(0x02cf00ba) ret=01f7:1460 ds=01ff
Ret KERNEL.52: FREEPROCINSTANCE() retval=0x0001 ret=01f7:1460 ds=01ff
Call USER.1: MESSAGEBOX(0x0000,0x01ff1246 "Runtime error 219 at 0004:1056.",0x00000000,0x1010) ret=01f7:2160 ds=01ff
</programlisting>
</para>
<para>
I think that the call to <function>MessageBox()</function>
in this example is <emphasis>not</emphasis> caused by a
wrong result value of some previously executed function
(it's happening quite often like that), but instead the
messagebox complains about a runtime error at
<literal>0x0004:0x1056</literal>.
</para>
<para>
As the segment value of the address is only
<literal>4</literal>, I think that that is only an internal
program value. But the offset address reveals something
quite interesting: Offset <literal>1056</literal> is
<emphasis>very</emphasis> close to the return address of
<function>FREELIBRARY()</function>:
<programlisting>
Call KERNEL.96: FREELIBRARY(0x031f) ret=01cf:105c ds=01ff
^^^^
</programlisting>
</para>
<para>
Provided that segment <literal>0x0004</literal> is indeed segment
<literal>0x1cf</literal>, we now we can use IDA (available at
<ulink url="ftp://ftp.uni-koeln.de/pc/msdos/programming/assembler/ida35bx.zip">
ftp://ftp.uni-koeln.de/pc/msdos/programming/assembler/ida35bx.zip</ulink>) to
disassemble the part that caused the error. We just have to find the address of
the call to <function>FreeLibrary()</function>. Some lines before that the
runtime error occurred. But be careful! In some cases you don't have to
disassemble the main program, but instead some DLL called by it in order to find
the correct place where the runtime error occurred. That can be determined by
finding the origin of the segment value (in this case <literal>0x1cf</literal>).
</para>
</listitem>
<listitem>
<para>
If you have created a relay file of some crashing
program and want to set a breakpoint at a certain
location which is not yet available as the program loads
the breakpoint's segment during execution, you may set a
breakpoint to <function>GetVersion16/32</function> as
those functions are called very often.
</para>
<para>
Then do a <userinput>c</userinput> until you are able to
set this breakpoint without error message.
</para>
</listitem>
<listitem>
<para>
Some useful programs:
</para>
<variablelist>
<varlistentry>
<term>
<application>IDA</application>:
<filename>
<ulink url="ftp://ftp.uni-koeln.de/pc/msdos/programming/assembler/ida35bx.zip">
ftp://ftp.uni-koeln.de/pc/msdos/programming/assembler/ida35bx.zip</ulink>
</filename>
</term>
<listitem>
<para>
<emphasis>Very</emphasis> good DOS disassembler ! It's badly needed
for debugging Wine sometimes.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<application>XRAY</application>:
<filename>
<ulink url="ftp://ftp.th-darmstadt.de/pub/machines/ms-dos/SimTel/msdos/asmutil/xray15.zip">
ftp://ftp.th-darmstadt.de/pub/machines/ms-dos/SimTel/msdos/asmutil/xray15.zip</ulink>
</filename>
</term>
<listitem>
<para>
Traces DOS calls (Int 21h, DPMI, ...). Use it with
Windows to correct file management problems etc.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<application>pedump</application>:
<filename>
<ulink url="http://oak.oakland.edu/pub/simtelnet/win95/prog/pedump.zip">
http://oak.oakland.edu/pub/simtelnet/win95/prog/pedump.zip</ulink>
</filename>
</term>
<listitem>
<para>
Dumps the imports and exports of a PE (Portable
Executable) DLL.
</para>
</listitem>
</varlistentry>
</variablelist>
</listitem>
</itemizedlist>
</sect2>
<sect2>
<title>Some basic debugger usages:</title>
<para>
After starting your program with
</para>
<screen>
wine -debug myprog.exe
</screen>
<para>
the program loads and you get a prompt at the program
starting point. Then you can set breakpoints:
</para>
<screen>
b RoutineName (by outine name) OR
b *0x812575 (by address)
</screen>
<para>
Then you hit <command>c</command> (continue) to run the
program. It stops at the breakpoint. You can type
</para>
<screen>
step (to step one line) OR
stepi (to step one machine instruction at a time;
here, it helps to know the basic 386
instruction set)
info reg (to see registers)
info stack (to see hex values in the stack)
info local (to see local variables)
list &lt;line number> (to list source code)
x &lt;variable name> (to examine a variable; only works if code
is not compiled with optimization)
x 0x4269978 (to examine a memory location)
? (help)
q (quit)
</screen>
<para>
By hitting <keycap>Enter</keycap>, you repeat the last
command.
</para>
</sect2>
</sect1>
<sect1 id="memory-addresses">
<title>Useful memory addresses</title>
<para>
Written by &name-andreas-mohr; <email>&email-andreas-mohr;</email>
</para>
<para>
Wine uses several different kinds of memory addresses.
</para>
<variablelist>
<varlistentry>
<term>
Win32/"normal" Wine addresses/Linux: linear addresses.
</term>
<listitem>
<para>
Linear addresses can be everything from 0x0 up to
0xffffffff. In Wine on Linux they are often around
e.g. 0x08000000, 0x00400000 (std. Win32 program load
address), 0x40000000. Every Win32 process has its own
private 4GB address space (that is, from 0x0 up to
0xffffffff).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
Win16 "enhanced mode": segmented addresses.
</term>
<listitem>
<para>
These are the "normal" Win16 addresses, called SEGPTR.
They have a segment:offset notation, e.g. 0x01d7:0x0012.
The segment part usually is a "selector", which *always*
has the lowest 3 bits set. Some sample selectors are
0x1f7, 0x16f, 0x8f. If these bits are set except for
the lowest bit, as e.g. with 0x1f6,xi then it might be a
handle to global memory. Just set the lowest bit to get
the selector in these cases. A selector kind of
"points" to a certain linear (see above) base address.
It has more or less three important attributes: segment
base address, segment limit, segment access rights.
</para>
<para>
Example:
</para>
<para>
Selector 0x1f7 (0x40320000, 0x0000ffff, r-x) So 0x1f7
has a base address of 0x40320000, the segment's last
address is 0x4032ffff (limit 0xffff), and it's readable
and executable. So an address of 0x1f7:0x2300 would be
the linear address of 0x40322300.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
DOS/Win16 "standard mode"
</term>
<listitem>
<para>
They, too, have a segment:offset notation. But they are
completely different from "normal" Win16 addresses, as
they just represent at most 1MB of memory: The segment
part can be anything from 0 to 0xffff, and it's the same
with the offset part.
</para>
<para>
Now the strange thing is the calculation that's behind
these addresses: Just calculate segment*16 + offset in
order to get a "linear DOS" address. So
e.g. 0x0f04:0x3628 results in 0xf040 + 0x3628 = 0x12668.
And the highest address you can get is 0xfffff (1MB), of
course. In Wine, this "linear DOS" address of 0x12668
has to be added to the linear base address of the
corresponding DOS memory allocated for dosmod in order
to get the true linear address of a DOS seg:offs
address. And make sure that you're doing this in the
correct process with the correct linear address space,
of course ;-)
</para>
</listitem>
</varlistentry>
</variablelist>
</sect1>
<sect1 id="dbg-config">
<title>III Configuration</title>
<title>Configuration</title>
<sect2>
<title>III.1 Registry configuration</title>
<title>Registry configuration</title>
<para>
The Windows' debugging API uses a registry entry to know
with debugger to invoke when an unhandled exception
occurs (see II.3 for some details). Two values in key
which debugger to invoke when an unhandled exception occurs
(see <link endterm="dbg-exception-title"
linkend="dbg-on-exception"></link> for some details). Two
values in key
</para>
<programlisting>
"MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug"
......@@ -280,6 +963,8 @@ winedbg "hl.exe -windowed"
(<command>WineDbg</command> can of course be used, but
any other Windows' debugging API aware debugger will
do).
The path to the debugger you chose to use must be reachable
via a DOS drive in the Wine config file !
</para>
</listitem>
</varlistentry>
......@@ -331,12 +1016,12 @@ winedbg "hl.exe -windowed"
</sect2>
<sect2>
<title>III.2 WineDbg configuration</title>
<title>WineDbg configuration</title>
<para>
<command>WineDbg</command> can be configured thru a number
of options. Those options are stored in the registry, on a
per user basis. The key is (in *my* registry)
per user basis. The key is (in <emphasis>my</emphasis> registry)
</para>
<programlisting>
[eric\\Software\\Wine\\WineDbg]
......@@ -344,7 +1029,7 @@ winedbg "hl.exe -windowed"
<para>
Those options can be read/written while inside
<command>WineDbg</command>, as part of the debugger
expressions. To refer to one of this option, its name must
expressions. To refer to one of these options, its name must
be prefixed by a <literal>$</literal> sign. For example,
</para>
<programlisting>
......@@ -367,7 +1052,7 @@ set $BreakAllThreadsStartup = 1
</para>
<sect3>
<title>III.2.1 Controling when the debugger is entered</title>
<title>Controlling when the debugger is entered</title>
<variablelist>
<varlistentry>
......@@ -437,7 +1122,7 @@ set $BreakAllThreadsStartup = 1
</sect3>
<sect3>
<title>III.2.2 Output handling</title>
<title>Output handling</title>
<variablelist>
<varlistentry>
......@@ -527,7 +1212,7 @@ UseXTerm = 1
</sect3>
<sect3>
<title>III.2.2 Context information</title>
<title>Context information</title>
<variablelist>
<varlistentry>
......@@ -559,25 +1244,14 @@ UseXTerm = 1
</para>
</sect3>
</sect2>
<sect2>
<title>III.3 Finding files</title>
<para>
WineDbg uses some lookup algorithms to find the files containing
the debugging information. For ELF files, the current directory,
the list of directories pointed by PATH, LD_LIBRARY_PATH are
searched (in that order). For Microsoft debugging files,
current directory, and directories pointed by _NT_SYMBOL_PATH and
_NT_ALT_SYMBOL_PATH (in that order) are searched.
</para>
</sect2>
</sect1>
<sect1 id="dbg-commands">
<title>IV WineDbg commands</title>
<title>WineDbg Command Reference</title>
<sect2>
<title>IV.1 Misc</title>
<title>Misc</title>
<screen>
abort aborts the debugger
......@@ -597,7 +1271,7 @@ mode 32 switch to 32 bit mode
</sect2>
<sect2>
<title>IV.2 Flow control</title>
<title>Flow control</title>
<screen>
cont continue execution until next breakpoint or exception.
......@@ -620,7 +1294,7 @@ finish do nexti commands until current function is exited
</sect2>
<sect2>
<title>IV.3 Breakpoints, watch points</title>
<title>Breakpoints, watch points</title>
<screen>
enable N enables (break|watch)point #N
......@@ -644,7 +1318,7 @@ info break lists all (break|watch)points (with state)
</sect2>
<sect2>
<title>IV.4 Stack manipulation</title>
<title>Stack manipulation</title>
<screen>
bt print calling stack of current thread
......@@ -659,7 +1333,7 @@ info local prints information on local variables for current
</sect2>
<sect2>
<title>IV.5 Directory & source file manipulation</title>
<title>Directory & source file manipulation</title>
<screen>
show dir
......@@ -687,7 +1361,7 @@ list foo.c:1,56 lists source lines from line 1 up to 56 in file foo.c
</sect2>
<sect2>
<title>IV.6 Displaying</title>
<title>Displaying</title>
<para>
A display is an expression that's evaluated and printed
......@@ -707,7 +1381,7 @@ undisplay N (same as del display)
</sect2>
<sect2>
<title>IV.7 Disassembly</title>
<title>Disassembly</title>
<screen>
disas disassemble from current position
......@@ -718,7 +1392,7 @@ disas &lt;expr&gt;,&lt;expr&gt;disassembles code between addresses specified by
</sect2>
<sect2>
<title>IV.8 Information on Wine's internals</title>
<title>Information on Wine's internals</title>
<screen>
info class &lt;id&gt; prints information on Windows's class &lt;id&gt;
......@@ -747,7 +1421,7 @@ walk modref (no longer avail)
</sect2>
<sect2>
<title>IV.9 Memory (reading, writing, typing)</title>
<title>Memory (reading, writing, typing)</title>
<screen>
x &lt;expr&gt; examines memory at &lt;expr&gt; address
......@@ -776,11 +1450,12 @@ b =&gt; 8 bit unsigned hexadecimal integer
</sect2>
</sect1>
<sect1 id="dbg-others">
<title>V Other debuggers</title>
<title>Other debuggers</title>
<sect2>
<title>V.1 Using other Unix debuggers</title>
<title>Using other Unix debuggers</title>
<para>
You can also use other debuggers (like
......@@ -795,7 +1470,7 @@ b =&gt; 8 bit unsigned hexadecimal integer
<varname>upids</varname> are for the Windows' application
running the desktop, the first thread of the application is
generally the third <varname>upid</varname>; when running a
WineLib program, the first thread of the application is
Winelib program, the first thread of the application is
generally the first <varname>upid</varname>)
</para>
<note>
......@@ -809,10 +1484,72 @@ b =&gt; 8 bit unsigned hexadecimal integer
thread you wish to debug.
</para>
</note>
<!-- *** Extra content spliced in from article by Andreas Mohr *** -->
<para>
Following text written by &name-andreas-mohr; <email>&email-andreas-mohr;</email>
</para>
<para>
Here's how to get info about the current execution status of a
certain Wine process:
</para>
<para>
Change into your Wine source dir and enter:
</para>
<screen>
$ gdb wine
</screen>
<para>
Switch to another console and enter <command>ps ax | grep
wine</command> to find all wine processes. Inside
<command>gdb</command>, repeat for all Wine processes:
</para>
<screen>
(gdb) attach <userinput>PID</userinput>
</screen>
<para>
with <userinput>PID</userinput> being the process ID of one of
the Wine processes. Use
</para>
<screen>
(gdb) bt
</screen>
<para>
to get the backtrace of the current Wine process, i.e. the
function call history. That way you can find out what the
current process is doing right now. And then you can use
several times:
</para>
<screen>
(gdb) n
</screen>
<para>
or maybe even
</para>
<screen>
(gdb) b <userinput>SomeFunction</userinput>
</screen>
<para>
and
</para>
<screen>
(gdb) c
</screen>
<para>
to set a breakpoint at a certain function and continue up to
that function. Finally you can enter
</para>
<screen>
(gdb) detach
</screen>
<para>
to detach from the Wine process.
</para>
<!-- *** End of xtra content *** -->
</sect2>
<sect2>
<title>V.2 Using other Windows debuggers</title>
<title>Using other Windows debuggers</title>
<para>
You can use any Windows' debugging API compliant debugger
......@@ -823,7 +1560,7 @@ b =&gt; 8 bit unsigned hexadecimal integer
</sect2>
<sect2>
<title>V.3 Main differences between winedbg and regular Unix debuggers</title>
<title>Main differences between winedbg and regular Unix debuggers</title>
<!-- FIXME: convert this into a table -->
<screen>
......@@ -846,8 +1583,9 @@ b =&gt; 8 bit unsigned hexadecimal integer
</sect2>
</sect1>
<sect1 id="dbg-limits">
<title>VI Limitations</title>
<title>Limitations</title>
<para>
16 bit processes are not supported (but calls to 16 bit code
......@@ -860,6 +1598,6 @@ b =&gt; 8 bit unsigned hexadecimal integer
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-parent-document:("wine-doc.sgml" "book" "part" "chapter" "")
sgml-parent-document:("wine-doc.sgml" "set" "book" "part" "chapter" "")
End:
-->
<chapter id="debugging">
<title>Debugging Wine</title>
<sect1 id="debug-msg">
<title>Debug Messages</title>
<title>Debug Logging</title>
<para>
written by Dimitrie O. Paun <email>dimi@cs.toronto.edu</email>, 28 Mar 1998
Written by &name-dimitrie-paun; <email>&email-dimitrie-paun;</email>, 28 Mar 1998
</para>
<para>
(Extracted from <filename>wine/documentation/debug-msgs</filename>)
......@@ -36,7 +33,7 @@
</para>
</important>
<sect2>
<sect1 id="dbg-classes">
<title>Debugging classes</title>
<para>
......@@ -151,9 +148,9 @@
off and certain classes of messages may be completely
disabled at compile time to reduce the size of Wine.
</para>
</sect2>
</sect1>
<sect2>
<sect1 id="dbg-channels">
<title>Debugging channels</title>
<para>
......@@ -202,9 +199,9 @@ dprintf_reg(stddeb, "Could not access key!\n");
WARN(reg, "Could not access key!\n");
</programlisting>
</note>
</sect2>
</sect1>
<sect2>
<sect1 id="dbg-using">
<title>How to use it</title>
<para>
......@@ -216,7 +213,7 @@ WARN(reg, "Could not access key!\n");
....
YYY(xxx, "&lt;message&gt;", ...);
YYY(xxx, "&lt;message>", ...);
</programlisting>
<para>
Some examples from the code:
......@@ -277,9 +274,9 @@ YYY(xxx, "&lt;message&gt;", ...);
</listitem>
</orderedlist>
</note>
</sect2>
</sect1>
<sect2>
<sect1 id="dbg-checking">
<title>Are we debugging?</title>
<para>
......@@ -310,9 +307,9 @@ if(TRACE_ON(atom)){
used only once!) are used in Wine.
</para>
</note>
</sect2>
</sect1>
<sect2>
<sect1 id="dbg-in-memory">
<title>In-memory messages</title>
<para>
......@@ -338,7 +335,7 @@ dbg_decl_str(name, len);
<para>
print in it with:
<programlisting>
dsprintf(name, "&lt;message&gt;", ...);
dsprintf(name, "&lt;message>", ...);
</programlisting>
which is just like a <function>sprintf</function>
function but instead of a C string as first parameter it
......@@ -370,13 +367,13 @@ void some_func(tabs)
LPINT16 p = (LPINT16)tabs;
dbg_decl_str(listbox, 256); /* declare the string */
for (i = 0; i &lt; descr-&gt;nb_tabs; i++) {
descr-&gt;tabs[i] = *p++&lt;&lt;1;
for (i = 0; i &lt; descr->nb_tabs; i++) {
descr->tabs[i] = *p++&lt;&lt;1;
if(TRACING(listbox)) /* write in it only if
dsprintf(listbox, "%hd ", descr-&gt;tabs[i]); /* we are gonna output it */
dsprintf(listbox, "%hd ", descr->tabs[i]); /* we are gonna output it */
}
TRACE(listbox, "Listbox %04x: settabstops %s",
wnd-&gt;hwndSelf, dbg_str(listbox)); /* output the whole thing */
wnd->hwndSelf, dbg_str(listbox)); /* output the whole thing */
}
</programlisting>
<para>
......@@ -390,23 +387,23 @@ void some_func(tabs)
LPINT16 p = (LPINT16)tabs;
dbg_decl_str(listbox, 256); /* declare the string */
for (i = 0; i &lt; descr-&gt;nb_tabs; i++) {
descr-&gt;tabs[i] = *p++&lt;&lt;1;
for (i = 0; i &lt; descr->nb_tabs; i++) {
descr->tabs[i] = *p++&lt;&lt;1;
if(TRACING(listbox)) /* write in it only if
dsprintf(listbox, "%hd ", descr-&gt;tabs[i]); /* we are gonna output it */
dsprintf(listbox, "%hd ", descr->tabs[i]); /* we are gonna output it */
}
TRACE(listbox, "Listbox %04x: settabstops %s\n",
wnd-&gt;hwndSelf, dbg_str(listbox)); /* output the whole thing */
wnd->hwndSelf, dbg_str(listbox)); /* output the whole thing */
dbg_reset_str(listbox); /* !!!reset the string!!! */
for (i = 0; i &lt; descr-&gt;extrainfo_nr; i++) {
descr-&gt;extrainfo = *p+1;
for (i = 0; i &lt; descr->extrainfo_nr; i++) {
descr->extrainfo = *p+1;
if(TRACING(listbox)) /* write in it only if
dsprintf(listbox,"%3d ",descr-&gt;extrainfo); /* we are gonna output it */
dsprintf(listbox,"%3d ",descr->extrainfo); /* we are gonna output it */
}
TRACE(listbox, "Listbox %04x: extrainfo %s\n",
wnd-&gt;hwndSelf, dbg_str(listbox)); /* output the whole thing */
wnd->hwndSelf, dbg_str(listbox)); /* output the whole thing */
}
</programlisting>
......@@ -459,9 +456,9 @@ if(YYY(xxx))
</listitem>
</itemizedlist>
</important>
</sect2>
</sect1>
<sect2>
<sect1 id="dbg-resource-ids">
<title>Resource identifiers</title>
<para>
......@@ -497,7 +494,7 @@ LPSTR debugres(const void *id);
returns a string of the form:
</para>
<programlisting>
'&lt;identifier&gt;'
'&lt;identifier>'
</programlisting>
<para>
Thus, to use it, do something on the following lines:
......@@ -509,9 +506,9 @@ LPSTR debugres(const void *id);
YYY(xxx, "resource is %s", debugres(myresource));
</programlisting>
</sect2>
</sect1>
<sect2>
<sect1 id="dbg-param">
<title>The <parameter>--debugmsg</parameter> command line option</title>
<para>
......@@ -598,9 +595,9 @@ LPSTR debugres(const void *id);
default</para>
</listitem>
</itemizedlist>
</sect2>
</sect1>
<sect2>
<sect1 id="dbg-compiling">
<title>Compiling Out Debugging Messages</title>
<para>
......@@ -620,9 +617,9 @@ LPSTR debugres(const void *id);
This feature has not been extensively tested--it may subtly
break some things.
</para>
</sect2>
</sect1>
<sect2>
<sect1 id="dbg-notes">
<title>A Few Notes on Style</title>
<para>
......@@ -632,7 +629,7 @@ LPSTR debugres(const void *id);
output format is the following:
</para>
<screen>
yyy:xxx:fff &lt;message&gt;
yyy:xxx:fff &lt;message>
where:
yyy = the class (fixme, err, warn, trace)
......@@ -641,7 +638,7 @@ where:
</screen>
<para>
these fields are output automatically. All you have to
provide is the &lt;message&gt; part.
provide is the &lt;message> part.
</para>
<para>
So here are some ideas:
......@@ -780,777 +777,13 @@ MSG( "Definition of drive %d is incorrect!\n", drive );
</para>
</listitem>
</itemizedlist>
</sect2>
</sect1>
<sect1 id="wine-debugger">
<title>Using the Wine Debugger</title>
<para>
written by Marcus Meissner <email>msmeissn@cip.informatik.uni-erlangen.de</email>,
additions welcome.
</para>
<para>
(Extracted from <filename>wine/documentation/debugging</filename>)
</para>
<para>
This file describes where to start debugging Wine. If at any
point you get stuck and want to ask for help, please read the
file <filename>documentation/bugreports</filename> for
information on how to write useful bug reports.
</para>
<sect2>
<title>Crashes</title>
<para>
These usually show up like this:
</para>
<screen>
|Unexpected Windows program segfault - opcode = 8b
|Segmentation fault in Windows program 1b7:c41.
|Loading symbols from ELF file /root/wine/wine...
|....more Loading symbols from ...
|In 16 bit mode.
|Register dump:
| CS:01b7 SS:016f DS:0287 ES:0000
| IP:0c41 SP:878a BP:8796 FLAGS:0246
| AX:811e BX:0000 CX:0000 DX:0000 SI:0001 DI:ffff
|Stack dump:
|0x016f:0x878a: 0001 016f ffed 0000 0000 0287 890b 1e5b
|0x016f:0x879a: 01b7 0001 000d 1050 08b7 016f 0001 000d
|0x016f:0x87aa: 000a 0003 0004 0000 0007 0007 0190 0000
|0x016f:0x87ba:
|
|0050: sel=0287 base=40211d30 limit=0b93f (bytes) 16-bit rw-
|Backtrace:
|0 0x01b7:0x0c41 (PXSRV_FONGETFACENAME+0x7c)
|1 0x01b7:0x1e5b (PXSRV_FONPUTCATFONT+0x2cd)
|2 0x01a7:0x05aa
|3 0x01b7:0x0768 (PXSRV_FONINITFONTS+0x81)
|4 0x014f:0x03ed (PDOXWIN_@SQLCURCB$Q6CBTYPEULN8CBSCTYPE+0x1b1)
|5 0x013f:0x00ac
|
|0x01b7:0x0c41 (PXSRV_FONGETFACENAME+0x7c): movw %es:0x38(%bx),%dx
</screen>
<para>
Steps to debug a crash. You may stop at any step, but please
report the bug and provide as much of the information
gathered to the newsgroup or the relevant developer as
feasible.
</para>
<orderedlist>
<listitem>
<para>
Get the reason for the crash. This is usually an access to
an invalid selector, an access to an out of range address
in a valid selector, popping a segmentregister from the
stack or the like. When reporting a crash, report this
<emphasis>whole</emphasis> crashdump even if it doesn't
make sense to you.
</para>
<para>
(In this case it is access to an invalid selector, for
<systemitem>%es</systemitem> is <literal>0000</literal>, as
seen in the register dump).
</para>
</listitem>
<listitem>
<para>
Determine the cause of the crash. Since this is usually
a primary/secondary reaction to a failed or misbehaving
Wine function, rerun Wine with <parameter>-debugmsg
+relay</parameter> added to the commandline. This will
generate quite a lot of output, but usually the reason is
located in the last call(s). Those lines usually look like
this:
</para>
<screen>
|Call KERNEL.90: LSTRLEN(0227:0692 "text") ret=01e7:2ce7 ds=0227
^^^^^^^^^ ^ ^^^^^^^^^ ^^^^^^ ^^^^^^^^^ ^^^^
| | | | | |Datasegment
| | | | |Return address
| | | |textual parameter
| | |
| | |Argument(s). This one is a win16 segmented pointer.
| |Function called.
|The module, the function is called in. In this case it is KERNEL.
|Ret KERNEL.90: LSTRLEN() retval=0x0004 ret=01e7:2ce7 ds=0227
^^^^^^
|Returnvalue is 16 bit and has the value 4.
</screen>
</listitem>
<listitem>
<para>
If you have found a misbehaving function, try to find out
why it misbehaves. Find the function in the source code.
Try to make sense of the arguments passed. Usually there is
a <function>TRACE(&lt;channel&gt;,"(...)\n");</function> at
the beginning of the function. Rerun wine with
<parameter>-debugmsg +xyz,+relay</parameter> added to the
commandline.
</para>
</listitem>
<listitem>
<para>
Additional information on how to debug using the internal
debugger can be found in
<filename>debugger/README</filename>.
</para>
</listitem>
<listitem>
<para>
If this information isn't clear enough or if you want to
know more about what's happening in the function itself,
try running wine with <parameter>-debugmsg
+all</parameter>, which dumps ALL included debug
information in wine.
</para>
</listitem>
<listitem>
<para>
If even that isn't enough, add more debug output for
yourself into the functions you find relevant. See
<filename>documentation/debug-msgs</filename>. You might
also try to run the program in <command>gdb</command>
instead of using the WINE-debugger. If you do that, use
<parameter>handle SIGSEGV nostop noprint</parameter> to
disable the handling of seg faults inside
<command>gdb</command> (needed for Win16). If you don't use
the <parameter>--desktop</parameter> or
<parameter>--managed</parameter> option, start the WINE
process with <parameter>--sync</parameter>, or chances are
good to get X into an unusable state.
</para>
</listitem>
<listitem>
<para>
You can also set a breakpoint for that function. Start wine
with the <parameter>--debug</parameter> option added to the
commandline. After loading the executable wine will enter
the internal debugger. Use <parameter>break
KERNEL_LSTRLEN</parameter> (replace by function you want
to debug, CASE IS RELEVANT) to set a breakpoint. Then use
<command>continue</command> to start normal
program-execution. Wine will stop if it reaches the
breakpoint. If the program isn't yet at the crashing call
of that function, use <command>continue</command> again
until you are about to enter that function. You may now
proceed with single-stepping the function until you reach
the point of crash. Use the other debugger commands to
print registers and the like.
</para>
</listitem>
</orderedlist>
</sect2>
<sect2>
<title>Program hangs, nothing happens</title>
<para>
Switch to UNIX shell, get the process-ID using <command>ps -a |
grep wine</command>, and do a <command>kill -HUP
&lt;pid&gt;</command> (without the &lt; and &gt;). Wine will
then enter its internal debugger and you can proceed as
explained above. Also, you can use
<parameter>--debug</parameter> switch and then you can get into
internal debugger by pressing
<keycombo><keycap>Ctrl</keycap><keycap>C</keycap></keycombo> in
the terminal where you run Wine.
</para>
</sect2>
<sect2>
<title>Program reports an error with a Messagebox</title>
<para>
Sometimes programs are reporting failure using more or
less nondescript messageboxes. We can debug this using the
same method as Crashes, but there is one problem... For
setting up a message box the program also calls Wine
producing huge chunks of debug code.
</para>
<para>
Since the failure happens usually directly before setting up
the Messagebox you can start wine with
<parameter>--debug</parameter> added to the commandline, set a
breakpoint at <function>MessageBoxA</function> (called by win16
and win32 programs) and proceed with
<command>continue</command>. With <parameter>--debugmsg
+all</parameter> Wine will now stop directly before setting
up the Messagebox. Proceed as explained above.
</para>
<para>
You can also run wine using <command>wine -debugmsg +relay
program.exe 2&gt;&1 | less -i</command> and in
<command>less</command> search for <quote>MessageBox</quote>.
</para>
</sect2>
<sect2>
<title>Disassembling programs:</title>
<para>
You may also try to disassemble the offending program to
check for undocumented features and/or use of them.
</para>
<para>
The best, freely available, disassembler for Win16 programs is
<application>Windows Codeback</application>, archivename
<filename>wcbxxx.zip</filename>, which usually can be found in
the <filename>Cica-Mirror</filename> subdirectory on the WINE
ftpsites. (See <filename>ANNOUNCE</filename>).
</para>
<para>
Disassembling win32 programs is possible using
<application>Windows Disassembler 32</application>, archivename
something like <filename>w32dsm87.zip</filename> (or similar)
on <systemitem class="systemname">ftp.winsite.com</systemitem>
and mirrors. The shareware version does not allow saving of
disassembly listings. You can also use the newer (and in the
full version better) <application>Interactive
Disassembler</application> (IDA) from the ftp sites mentioned
at the end of the document. Understanding disassembled code is
mostly a question of exercise.
</para>
<para>
Most code out there uses standard C function entries (for it
is usually written in C). Win16 function entries usually
look like that:
</para>
<programlisting>
push bp
mov bp, sp
... function code ..
retf XXXX &lt;--------- XXXX is number of bytes of arguments
</programlisting>
<para>
This is a <function>FAR</function> function with no local
storage. The arguments usually start at
<literal>[bp+6]</literal> with increasing offsets. Note, that
<literal>[bp+6]</literal> belongs to the
<emphasis>rightmost</emphasis> argument, for exported win16
functions use the PASCAL calling convention. So, if we use
<function>strcmp(a,b)</function> with <parameter>a</parameter>
and <parameter>b</parameter> both 32 bit variables
<parameter>b</parameter> would be at <literal>[bp+6]</literal>
and <parameter>a</parameter> at <literal>[bp+10]</literal>.
</para>
<para>
Most functions make also use of local storage in the stackframe:
</para>
<programlisting>
enter 0086, 00
... function code ...
leave
retf XXXX
</programlisting>
<para>
This does mostly the same as above, but also adds
<literal>0x86</literal> bytes of stackstorage, which is
accessed using <literal>[bp-xx]</literal>. Before calling a
function, arguments are pushed on the stack using something
like this:
</para>
<programlisting>
push word ptr [bp-02] &lt;- will be at [bp+8]
push di &lt;- will be at [bp+6]
call KERNEL.LSTRLEN
</programlisting>
<para>
Here first the selector and then the offset to the passed
string are pushed.
</para>
</sect2>
<sect2>
<title>Sample debugging session:</title>
<para>
Let's debug the infamous Word <filename>SHARE.EXE</filename>
messagebox:
</para>
<screen>
|marcus@jet $ wine winword.exe
| +---------------------------------------------+
| | ! You must leave Windows and load SHARE.EXE|
| | before starting Word. |
| +---------------------------------------------+
</screen>
<screen>
|marcus@jet $ wine winword.exe -debugmsg +relay -debug
|CallTo32(wndproc=0x40065bc0,hwnd=000001ac,msg=00000081,wp=00000000,lp=00000000)
|Win16 task 'winword': Breakpoint 1 at 0x01d7:0x001a
|CallTo16(func=0127:0070,ds=0927)
|Call WPROCS.24: TASK_RESCHEDULE() ret=00b7:1456 ds=0927
|Ret WPROCS.24: TASK_RESCHEDULE() retval=0x8672 ret=00b7:1456 ds=0927
|CallTo16(func=01d7:001a,ds=0927)
| AX=0000 BX=3cb4 CX=1f40 DX=0000 SI=0000 DI=0927 BP=0000 ES=11f7
|Loading symbols: /home/marcus/wine/wine...
|Stopped on breakpoint 1 at 0x01d7:0x001a
|In 16 bit mode.
|Wine-dbg&gt;break MessageBoxA &lt;---- Set Breakpoint
|Breakpoint 2 at 0x40189100 (MessageBoxA [msgbox.c:190])
|Wine-dbg&gt;c &lt;---- Continue
|Call KERNEL.91: INITTASK() ret=0157:0022 ds=08a7
| AX=0000 BX=3cb4 CX=1f40 DX=0000 SI=0000 DI=08a7 ES=11d7 EFL=00000286
|CallTo16(func=090f:085c,ds=0dcf,0x0000,0x0000,0x0000,0x0000,0x0800,0x0000,0x0000,0x0dcf)
|... &lt;----- Much debugoutput
|Call KERNEL.136: GETDRIVETYPE(0x0000) ret=060f:097b ds=0927
^^^^^^ Drive 0 (A:)
|Ret KERNEL.136: GETDRIVETYPE() retval=0x0002 ret=060f:097b ds=0927
^^^^^^ DRIVE_REMOVEABLE
(It is a floppy diskdrive.)
|Call KERNEL.136: GETDRIVETYPE(0x0001) ret=060f:097b ds=0927
^^^^^^ Drive 1 (B:)
|Ret KERNEL.136: GETDRIVETYPE() retval=0x0000 ret=060f:097b ds=0927
^^^^^^ DRIVE_CANNOTDETERMINE
(I don't have drive B: assigned)
|Call KERNEL.136: GETDRIVETYPE(0x0002) ret=060f:097b ds=0927
^^^^^^^ Drive 2 (C:)
|Ret KERNEL.136: GETDRIVETYPE() retval=0x0003 ret=060f:097b ds=0927
^^^^^^ DRIVE_FIXED
(specified as a harddisk)
|Call KERNEL.97: GETTEMPFILENAME(0x00c3,0x09278364"doc",0x0000,0927:8248) ret=060f:09b1 ds=0927
^^^^^^ ^^^^^ ^^^^^^^^^
| | |buffer for fname
| |temporary name ~docXXXX.tmp
|Force use of Drive C:.
|Warning: GetTempFileName returns 'C:~doc9281.tmp', which doesn't seem to be writeable.
|Please check your configuration file if this generates a failure.
</screen>
<para>
Whoops, it even detects that something is wrong!
</para>
<screen>
|Ret KERNEL.97: GETTEMPFILENAME() retval=0x9281 ret=060f:09b1 ds=0927
^^^^^^ Temporary storage ID
|Call KERNEL.74: OPENFILE(0x09278248"C:~doc9281.tmp",0927:82da,0x1012) ret=060f:09d8 ds=0927
^^^^^^^^^^^^^^^^ ^^^^^^^^^ ^^^^^^^
|filename |OFSTRUCT |open mode:
OF_CREATE|OF_SHARE_EXCLUSIVE|OF_READWRITE
</screen>
<para>
This fails, since my <medialabel>C:</medialabel> drive is in
this case mounted readonly.
</para>
<screen>
|Ret KERNEL.74: OPENFILE() retval=0xffff ret=060f:09d8 ds=0927
^^^^^^ HFILE_ERROR16, yes, it failed.
|Call USER.1: MESSAGEBOX(0x0000,0x09278376"Sie mussen Windows verlassen und SHARE.EXE laden bevor Sie Word starten.",0x00000000,0x1030) ret=060f:084f ds=0927
</screen>
<para>
And MessageBox'ed.
</para>
<screen>
|Stopped on breakpoint 2 at 0x40189100 (MessageBoxA [msgbox.c:190])
|190 { &lt;- the sourceline
In 32 bit mode.
Wine-dbg&gt;
</screen>
<para>
The code seems to find a writeable harddisk and tries to create
a file there. To work around this bug, you can define
<medialabel>C:</medialabel> as a networkdrive, which is ignored
by the code above.
</para>
</sect2>
<sect2>
<title>Debugging Tips</title>
<para>
Here are some useful debugging tips, added by Andreas Mohr:
</para>
<itemizedlist>
<listitem>
<para>
If you have a program crashing at such an early loader phase that you can't
use the Wine debugger normally, but Wine already executes the program's
start code, then you may use a special trick. You should do a
<programlisting>
wine --debugmsg +relay program
</programlisting>
to get a listing of the functions the program calls in its start function.
Now you do a
<programlisting>
wine --debug winfile.exe
</programlisting>
</para>
<para>
This way, you get into <command>Wine-dbg</command>. Now you
can set a breakpoint on any function the program calls in
the start function and just type <userinput>c</userinput>
to bypass the eventual calls of Winfile to this function
until you are finally at the place where this function gets
called by the crashing start function. Now you can proceed
with your debugging as usual.
</para>
</listitem>
<listitem>
<para>
If you try to run a program and it quits after showing an error messagebox,
the problem can usually be identified in the return value of one of the
functions executed before <function>MessageBox()</function>.
That's why you should re-run the program with e.g.
<programlisting>
wine --debugmsg +relay &lt;program name&gt; &&gt;relmsg
</programlisting>
Then do a <command>more relmsg</command> and search for the
last occurrence of a call to the string "MESSAGEBOX". This is a line like
<programlisting>
Call USER.1: MESSAGEBOX(0x0000,0x01ff1246 "Runtime error 219 at 0004:1056.",0x00000000,0x1010) ret=01f7:2160 ds=01ff
</programlisting>
In my example the lines before the call to
<function>MessageBox()</function> look like that:
<programlisting>
Call KERNEL.96: FREELIBRARY(0x0347) ret=01cf:1033 ds=01ff
CallTo16(func=033f:0072,ds=01ff,0x0000)
Ret KERNEL.96: FREELIBRARY() retval=0x0001 ret=01cf:1033 ds=01ff
Call KERNEL.96: FREELIBRARY(0x036f) ret=01cf:1043 ds=01ff
CallTo16(func=0367:0072,ds=01ff,0x0000)
Ret KERNEL.96: FREELIBRARY() retval=0x0001 ret=01cf:1043 ds=01ff
Call KERNEL.96: FREELIBRARY(0x031f) ret=01cf:105c ds=01ff
CallTo16(func=0317:0072,ds=01ff,0x0000)
Ret KERNEL.96: FREELIBRARY() retval=0x0001 ret=01cf:105c ds=01ff
Call USER.171: WINHELP(0x02ac,0x01ff05b4 "COMET.HLP",0x0002,0x00000000) ret=01cf:1070 ds=01ff
CallTo16(func=0117:0080,ds=01ff)
Call WPROCS.24: TASK_RESCHEDULE() ret=00a7:0a2d ds=002b
Ret WPROCS.24: TASK_RESCHEDULE() retval=0x0000 ret=00a7:0a2d ds=002b
Ret USER.171: WINHELP() retval=0x0001 ret=01cf:1070 ds=01ff
Call KERNEL.96: FREELIBRARY(0x01be) ret=01df:3e29 ds=01ff
Ret KERNEL.96: FREELIBRARY() retval=0x0000 ret=01df:3e29 ds=01ff
Call KERNEL.52: FREEPROCINSTANCE(0x02cf00ba) ret=01f7:1460 ds=01ff
Ret KERNEL.52: FREEPROCINSTANCE() retval=0x0001 ret=01f7:1460 ds=01ff
Call USER.1: MESSAGEBOX(0x0000,0x01ff1246 "Runtime error 219 at 0004:1056.",0x00000000,0x1010) ret=01f7:2160 ds=01ff
</programlisting>
</para>
<para>
I think that the call to <function>MessageBox()</function>
in this example is <emphasis>not</emphasis> caused by a
wrong result value of some previously executed function
(it's happening quite often like that), but instead the
messagebox complains about a runtime error at
<literal>0x0004:0x1056</literal>.
</para>
<para>
As the segment value of the address is only
<literal>4</literal>, I think that that is only an internal
program value. But the offset address reveals something
quite interesting: Offset <literal>1056</literal> is
<emphasis>very</emphasis> close to the return address of
<function>FREELIBRARY()</function>:
<programlisting>
Call KERNEL.96: FREELIBRARY(0x031f) ret=01cf:105c ds=01ff
^^^^
</programlisting>
</para>
<para>
Provided that segment <literal>0x0004</literal> is indeed segment
<literal>0x1cf</literal>, we now we can use IDA (available at
<ulink url="ftp://ftp.uni-koeln.de/pc/msdos/programming/assembler/ida35bx.zip">
ftp://ftp.uni-koeln.de/pc/msdos/programming/assembler/ida35bx.zip</ulink>) to
disassemble the part that caused the error. We just have to find the address of
the call to <function>FreeLibrary()</function>. Some lines before that the
runtime error occurred. But be careful! In some cases you don't have to
disassemble the main program, but instead some DLL called by it in order to find
the correct place where the runtime error occurred. That can be determined by
finding the origin of the segment value (in this case <literal>0x1cf</literal>).
</para>
</listitem>
<listitem>
<para>
If you have created a relay file of some crashing
program and want to set a breakpoint at a certain
location which is not yet available as the program loads
the breakpoint's segment during execution, you may set a
breakpoint to <function>GetVersion16/32</function> as
those functions are called very often.
</para>
<para>
Then do a <userinput>c</userinput> until you are able to
set this breakpoint without error message.
</para>
</listitem>
<listitem>
<para>
Some useful programs:
</para>
<variablelist>
<varlistentry>
<term>
<application>IDA</application>:
<filename>
<ulink url="ftp://ftp.uni-koeln.de/pc/msdos/programming/assembler/ida35bx.zip">
ftp://ftp.uni-koeln.de/pc/msdos/programming/assembler/ida35bx.zip</ulink>
</filename>
</term>
<listitem>
<para>
*Very* good DOS disassembler ! It's badly needed
for debugging Wine sometimes.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<application>XRAY</application>:
<filename>
<ulink url="ftp://ftp.th-darmstadt.de/pub/machines/ms-dos/SimTel/msdos/asmutil/xray15.zip">
ftp://ftp.th-darmstadt.de/pub/machines/ms-dos/SimTel/msdos/asmutil/xray15.zip</ulink>
</filename>
</term>
<listitem>
<para>
Traces DOS calls (Int 21h, DPMI, ...). Use it with
Windows to correct file management problems etc.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<application>pedump</application>:
<filename>
<ulink url="http://oak.oakland.edu/pub/simtelnet/win95/prog/pedump.zip">
http://oak.oakland.edu/pub/simtelnet/win95/prog/pedump.zip</ulink>
</filename>
</term>
<listitem>
<para>
Dumps the imports and exports of a PE (Portable
Executable) DLL.
</para>
</listitem>
</varlistentry>
</variablelist>
</listitem>
</itemizedlist>
</sect2>
<sect2>
<title>Some basic debugger usages:</title>
<para>
After starting your program with
</para>
<screen>
wine -debug myprog.exe
</screen>
<para>
the program loads and you get a prompt at the program
starting point. Then you can set breakpoints:
</para>
<screen>
b RoutineName (by outine name) OR
b *0x812575 (by address)
</screen>
<para>
Then you hit <command>c</command> (continue) to run the
program. It stops at the breakpoint. You can type
</para>
<screen>
step (to step one line) OR
stepi (to step one machine instruction at a time;
here, it helps to know the basic 386
instruction set)
info reg (to see registers)
info stack (to see hex values in the stack)
info local (to see local variables)
list &lt;line number&gt; (to list source code)
x &lt;variable name&gt; (to examine a variable; only works if code
is not compiled with optimization)
x 0x4269978 (to examine a memory location)
? (help)
q (quit)
</screen>
<para>
By hitting <keycap>Enter</keycap>, you repeat the last
command.
</para>
</sect2>
</sect1>
<sect1 id="cvs-regression">
<title>How to do regression testing using Cvs</title>
<para>
written by Gerard Patel (???)
</para>
<para>
(Extracted from <filename>wine/documentation/bugreports</filename>)
</para>
<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 occured. This is
*NOT* for casual users.
</para>
<orderedlist>
<listitem>
<para>
Get the 'full cvs' archive from winehq. This archive is
the cvs tree but with the tags controling the versioning
system. It's a big file (> 15 meg) with a name like
full-cvs-&lt;last update date&gt; (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 -zxffull-cvs-2000-05-20.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
cd /home/gerard
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>
</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 -d $CVSROOT update -D "1999-06-01"
</screen>
</para>
<para>
The date format is <literal>YYYY-MM-DD</literal>.
</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 *newer* 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>
When you have found the exact date when a bug was added to
the cvs tree, use something like :
<screen>
cvs -d $CVSROOT diff -D "1999-07-10" -D "1999-07-12"
</screen>
to get all the differences between the last cvs tree
version known to work and code that first displayed the
misbehavior.
</para>
<note>
<para>
I did not include flags for <command>diff</command>
since they are in my <filename>.cvsrc</filename> file:
</para>
<screen>
cvs -z 3
update -dPA
diff -u
</screen>
</note>
<para>
From this diff file, particularly the file names, and the
<filename>ChangeLog</filename>, it's usually possible to
find the different individual patches that were done at
this time.
</para>
<para>
If any non-programmer reads this, the fastest method to get
at the point where the problem occured is to use a binary
search, that is, if the problem occured 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>
</listitem>
<listitem>
<para>
The next step is to start from the last working version
and to dig the individual contributions from
<ulink url="http://www.integrita.com/cgi-local/lwgate.pl/WINE-PATCHES/">
http://www.integrita.com/cgi-local/lwgate.pl/WINE-PATCHES/</ulink>
(where the Wine patches mailing list is archived)
</para>
<para>
If the patch was done by the Wine maintainer or if it was
sent directly to his mail address without going first through
<ulink url="mailto:wine-patches@winehq.com">wine-patches</ulink>,
you are out of luck as you will never find the patch in
the archive. If it is, it's often possible to apply the
patches one by one to last working cvs snapshot, compile and test.
If you have saved the next candidate as
<filename>/home/gerard/buggedpatch1.txt</filename>:
</para>
<screen>
cd /home/gerard/wine
patch -p 0 &lt; /home/gerard/buggedpatch1.txt
</screen>
<para>
Beware that the committed patch is not always identical to
the patch that the author sent to wine-patches, as
sometimes the Wine maintainer changes things a bit.
</para>
<para>
If you find one patch that is getting the cvs source tree to
reproduce the problem, you have almost won; post the problem on
<systemitem>comp.emulators.windows.wine</systemitem> and 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>
</chapter>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-parent-document:("wine-doc.sgml" "book" "part" "chapter" "")
sgml-parent-document:("wine-doc.sgml" "set" "book" "part" "chapter" "")
End:
-->
<!DOCTYPE style-sheet PUBLIC "-//James Clark//DTD DSSSL Style Sheet//EN" [
<!ENTITY walsh-style PUBLIC "-//Norman Walsh//DOCUMENT DocBook HTML Stylesheet//EN" CDATA DSSSL>
<!ENTITY cygnus-style SYSTEM "/usr/lib/sgml/stylesheet/dsssl/docbook/cygnus/cygnus-both.dsl" CDATA DSSSL>
]>
<style-sheet>
<style-specification id="html" use="docbook">
<style-specification-body>
(define %use-id-as-filename% #t)
(define %html-ext% ".html")
(define %html-header-tags% '())
;;(define %stylesheet% "../../winehq.css")
;;(define %stylesheet-type% "text/css")
(define %shade-verbatim% #t)
(define %section-autolabel% #t)
;; Customize the body tag color attributes
(define %body-attr%
(list
(list "BGCOLOR" "#FFFFFF")
(list "TEXT" "#000000")
(list "LINK" "#a50d0d")
(list "VLINK" "#505050")
(list "ALINK" "#a50d0d")))
;; Change the background color of programlisting and screen, etc.
(define ($shade-verbatim-attr$)
(list
(list "BORDER" "0")
;(list "BGCOLOR" "#E0E0E0") ; light grey
(list "BGCOLOR" "#E0D0D0") ; light grayish red
;(list "BGCOLOR" "#bc8686") ; dark rose
;(list "BGCOLOR" "#FFD39B") ; burlywood1 (tan)
;(list "BGCOLOR" "#FFE7BA") ; wheat1 (light tan)
(list "WIDTH" ($table-width$))))
;; Customize systemitem element to have different formatting, according
;; to which class attribute it contains.
(element systemitem
(let ((class (attribute-string (normalize "class"))))
(cond
((equal? class (normalize "systemname")) ($italic-mono-seq$))
((equal? class (normalize "constant")) ($mono-seq$))
(else ($charseq$)))))
;; Okay, this is a little tricky. By default, it appears that setinfo is
;; completely turned off (with empty-sosofo). The setinfo title is extracted
;; through some other means, so we can ignore it when we process the setinfo
;; below.
;; Process setinfo element
(element setinfo (process-children))
;; Ignore title element -- otherwise it'll appear alongside the releaseinfo
;; element. If we add any other elements to setinfo, we'll have to blank them
;; out here, also.
(element (setinfo title)
(empty-sosofo))
;; Enclose releaseinfo element in italics
(element (setinfo releaseinfo)
; (make element gi: "i"
; (process-children)))
(process-children))
</style-specification-body>
</style-specification>
<external-specification id="docbook" document="walsh-style">
</style-sheet>
<chapter id="dlls">
<title>Wine Builtin DLLs</title>
<title>Wine Builtin DLLs Overview</title>
<para>A more detailed look at Wine's builtin DLLs...</para>
<sect1 id="common-controls">
......@@ -11,7 +11,7 @@
</bridgehead>
<para>
written by Eric Kohl &lt;ekohl@abo.rhein-zeitung.de&gt;
Written by &name-eric-kohl; <email>&email-eric-kohl;</email>
</para>
<para>
(Extracted from <filename>wine/documentation/common_controls</filename>)
......@@ -180,7 +180,9 @@
<varlistentry>
<term>Author:</term>
<listitem>
<para>Dummy written by Eric Kohl. &lt;ekohl@abo.rhein-zeitung.de&gt;</para>
<para>
Dummy written by &name-eric-kohl; <email>&email-eric-kohl;</email>
</para>
</listitem>
</varlistentry>
<varlistentry>
......@@ -205,7 +207,9 @@
<varlistentry>
<term>Author:</term>
<listitem>
<para>Dummy written by Eric Kohl. &lt;ekohl@abo.rhein-zeitung.de&gt;</para>
<para>
Dummy written by &name-eric-kohl; <email>&email-eric-kohl;</email>
</para>
</listitem>
</varlistentry>
<varlistentry>
......@@ -230,7 +234,9 @@
<varlistentry>
<term>Author:</term>
<listitem>
<para>Dummy written by Eric Kohl. &lt;ekohl@abo.rhein-zeitung.de&gt;</para>
<para>
Dummy written by &name-eric-kohl; <email>&email-eric-kohl;</email>
</para>
</listitem>
</varlistentry>
<varlistentry>
......@@ -255,7 +261,9 @@
<varlistentry>
<term>Author:</term>
<listitem>
<para>Dummy written by Eric Kohl. &lt;ekohl@abo.rhein-zeitung.de&gt;</para>
<para>
Dummy written by &name-eric-kohl; <email>&email-eric-kohl;</email>
</para>
</listitem>
</varlistentry>
<varlistentry>
......@@ -280,7 +288,9 @@
<varlistentry>
<term>Author:</term>
<listitem>
<para>Dummy written by Alex Priem. &lt;alexp@sci.kun.nl&gt;</para>
<para>
Dummy written by &name-alex-priem; <email>&email-alex-priem;</email>
</para>
</listitem>
</varlistentry>
<varlistentry>
......@@ -305,7 +315,9 @@
<varlistentry>
<term>Author:</term>
<listitem>
<para>Eric Kohl &lt;ekohl@abo.rhein-zeitung.de&gt;</para>
<para>
Dummy written by &name-eric-kohl; <email>&email-eric-kohl;</email>
</para>
</listitem>
</varlistentry>
<varlistentry>
......@@ -334,7 +346,9 @@
<varlistentry>
<term>Author:</term>
<listitem>
<para>Dummy written by Eric Kohl. &lt;ekohl@abo.rhein-zeitung.de&gt;</para>
<para>
Written by &name-eric-kohl; <email>&email-eric-kohl;</email>
</para>
</listitem>
</varlistentry>
<varlistentry>
......@@ -359,7 +373,9 @@
<varlistentry>
<term>Author:</term>
<listitem>
<para>Eric Kohl &lt;ekohl@abo.rhein-zeitung.de&gt;</para>
<para>
Dummy written by &name-eric-kohl; <email>&email-eric-kohl;</email>
</para>
</listitem>
</varlistentry>
<varlistentry>
......@@ -379,8 +395,8 @@
<term>Author:</term>
<listitem>
<para>
Dummy written by Eric Kohl. &lt;ekohl@abo.rhein-zeitung.de&gt;,
Alex Priem &lt;alexp@sci.kun.nl&gt;
Dummy written by &name-eric-kohl; <email>&email-eric-kohl;</email>,
&name-alex-priem; <email>&email-alex-priem;</email>
</para>
</listitem>
</varlistentry>
......@@ -403,16 +419,19 @@
<para>Dummy written by: </para>
<itemizedlist>
<listitem>
<para>Eric Kohl. &lt;ekohl@abo.rhein-zeitung.de&gt;</para>
<para>
Written by &name-eric-kohl; <email>&email-eric-kohl;</email>
</para>
</listitem>
<listitem>
<para>Luc Tourangeau &lt;luc@macadamian.com&gt;</para>
<para>&name-luc-tourangeau; <email>&email-luc-tourangeau;</email></para>
</listitem>
<listitem>
<para>Koen Deforche &lt;jozef@kotnet.org&gt;</para>
<para>&name-koen-deforche; <email>&email-koen-deforche;</email></para>
</listitem>
<listitem>
<para>Francis Beaudet &lt;francis@macadamian.com&gt; and the "Corel-Team"</para>
<para>&name-francis-beaudet; <email>&email-francis-beaudet;</email>
and the "Corel Team"</para>
</listitem>
</itemizedlist>
</listitem>
......@@ -443,7 +462,9 @@
<varlistentry>
<term>Author:</term>
<listitem>
<para>Dummy written by Eric Kohl. &lt;ekohl@abo.rhein-zeitung.de&gt;</para>
<para>
Written by &name-eric-kohl; <email>&email-eric-kohl;</email>
</para>
</listitem>
</varlistentry>
<varlistentry>
......@@ -468,7 +489,9 @@
<varlistentry>
<term>Author:</term>
<listitem>
<para>Dummy written by Eric Kohl. &lt;ekohl@abo.rhein-zeitung.de&gt;</para>
<para>
Written by &name-eric-kohl; <email>&email-eric-kohl;</email>
</para>
</listitem>
</varlistentry>
<varlistentry>
......@@ -493,7 +516,9 @@
<varlistentry>
<term>Author:</term>
<listitem>
<para>Dummy written by Eric Kohl. &lt;ekohl@abo.rhein-zeitung.de&gt;</para>
<para>
Written by &name-eric-kohl; <email>&email-eric-kohl;</email>
</para>
</listitem>
</varlistentry>
<varlistentry>
......@@ -543,8 +568,8 @@
<term>Author:</term>
<listitem>
<para>
Anders Carlsson &lt;anders.carlsson@linux.nu&gt; and
Francis Beaudet &lt;francis@macadamian.com&gt;
&name-anders-carlsson; <email>&email-anders-carlsson;</email> and
&name-francis-beaudet; <email>&email-francis-beaudet;</email>
</para>
</listitem>
</varlistentry>
......@@ -570,7 +595,9 @@
<varlistentry>
<term>Author:</term>
<listitem>
<para>Eric Kohl &lt;ekohl@abo.rhein-zeitung.de&gt;</para>
<para>
Written by &name-eric-kohl; <email>&email-eric-kohl;</email>
</para>
</listitem>
</varlistentry>
<varlistentry>
......@@ -623,7 +650,9 @@
<varlistentry>
<term>Author:</term>
<listitem>
<para>Anders Carlsson &lt;anders.carlsson@linux.nu&gt;</para>
<para>
&name-anders-carlsson; <email>&email-anders-carlsson;</email>
</para>
</listitem>
</varlistentry>
<varlistentry>
......@@ -642,7 +671,9 @@
<varlistentry>
<term>Author:</term>
<listitem>
<para>Eric Kohl &lt;ekohl@abo.rhein-zeitung.de&gt;</para>
<para>
Written by &name-eric-kohl; <email>&email-eric-kohl;</email>
</para>
</listitem>
</varlistentry>
<varlistentry>
......@@ -664,7 +695,9 @@
<varlistentry>
<term>Author:</term>
<listitem>
<para>Eric Kohl &lt;ekohl@abo.rhein-zeitung.de&gt;</para>
<para>
Written by &name-eric-kohl; <email>&email-eric-kohl;</email>
</para>
</listitem>
</varlistentry>
<varlistentry>
......@@ -691,8 +724,8 @@
<term>Author:</term>
<listitem>
<para>
Dummy written by Eric Kohl &lt;ekohl@abo.rhein-zeitung.de&gt;,
Alex Priem &lt;alexp@sci.kun.nl&gt;
Written by &name-eric-kohl; <email>&email-eric-kohl;</email> and
&name-alex-priem; <email>&email-alex-priem;</email>
</para>
</listitem>
</varlistentry>
......@@ -712,13 +745,17 @@
<varlistentry>
<term>Author:</term>
<listitem>
<para>Dummy written by Eric Kohl., Alex Priem &lt;alexp@sci.kun.nl&gt;</para>
<para>
Written by &name-eric-kohl; <email>&email-eric-kohl;</email> and
&name-alex-priem; <email>&email-alex-priem;</email>, fixes by
&name-aric-stewart; <email>&email-aric-stewart;</email>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Status:</term>
<listitem>
<para>Under construction.</para>
<para>Quite usable already.</para>
</listitem>
</varlistentry>
</variablelist>
......@@ -733,7 +770,7 @@
<listitem>
<para>
Original implementation by Dimitrie O. Paun.
Some minor changes by Eric Kohl &lt;ekohl@abo.rhein-zeitung.de&gt;.
Some minor changes by &name-eric-kohl; <email>&email-eric-kohl;</email>.
</para>
</listitem>
</varlistentry>
......@@ -798,7 +835,7 @@
</para>
<sect3>
<title>5.1 Dymnamic Storage Array (DSA)</title>
<title>5.1 Dynamic Storage Array (DSA)</title>
<para>
The DSA functions are used to store and manage dynamic
......@@ -903,6 +940,6 @@
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-parent-document:("wine-doc.sgml" "book" "part" "chapter" "")
sgml-parent-document:("wine-doc.sgml" "set" "book" "part" "chapter" "")
End:
-->
......@@ -6,7 +6,7 @@
<title>Writing Wine API Documentation</title>
<para>
written by (???)
Written by &name-douglas-ridgway; <email>&email-douglas-ridgway;</email>
</para>
<para>
(Extracted from <filename>wine/documentation/README.documentation</filename>)
......@@ -18,7 +18,7 @@
</para>
<screen>
/******************************************************************
* CopyMetaFile32A (GDI32.23)
* CopyMetaFileA (GDI32.23)
*
* Copies the metafile corresponding to hSrcMetaFile to either
* a disk file, if a filename is given, or to a new memory based
......@@ -32,8 +32,8 @@
*
* Copying to disk returns NULL even if successful.
*/
HMETAFILE32 WINAPI CopyMetaFile32A(
HMETAFILE32 hSrcMetaFile, /* handle of metafile to copy */
HMETAFILE WINAPI CopyMetaFileA(
HMETAFILE hSrcMetaFile, /* handle of metafile to copy */
LPCSTR lpFilename /* filename if copying to a file */
) { ... }
</screen>
......@@ -46,17 +46,17 @@ CopyMetaFileA(3w) CopyMetaFileA(3w)
NAME
CopyMetaFileA - CopyMetaFile32A (GDI32.23)
CopyMetaFileA (GDI32.23)
SYNOPSIS
HMETAFILE32 CopyMetaFileA
HMETAFILE CopyMetaFileA
(
HMETAFILE32 hSrcMetaFile,
HMETAFILE hSrcMetaFile,
LPCSTR lpFilename
);
PARAMETERS
HMETAFILE32 hSrcMetaFile
HMETAFILE hSrcMetaFile
Handle of metafile to copy.
LPCSTR lpFilename
......@@ -84,6 +84,6 @@ SEE ALSO
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-parent-document:("wine-doc.sgml" "book" "part" "chapter" "")
sgml-parent-document:("wine-doc.sgml" "set" "book" "part" "chapter" "")
End:
-->
......@@ -5,7 +5,7 @@
<title>Fonts</title>
<para>
written by ???
Written by &name-alex-korobka; <email>&email-alex-korobka;</email>
</para>
<para>
(Extracted from <filename>wine/documentation/fonts</filename>)
......@@ -43,7 +43,7 @@
<para>
Convert <filename>.bdf</filename> files produced by Step
1 into <filename>.pcf</filename> files with
<command>bdftopcf -o &lt;target file&gt; &lt;original bdf-file&gt;</command>.
<command>bdftopcf</command>.
</para>
</listitem>
<listitem>
......@@ -493,6 +493,6 @@ FontPath "tcp/localhost:7100"
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-parent-document:("wine-doc.sgml" "book" "chapter" "")
sgml-parent-document:("wine-doc.sgml" "set" "book" "chapter" "")
End:
-->
<chapter id="getting-wine">
<title>Getting Wine</title>
<sect1>
<title>The Many Forms of Wine</title>
<para>
The standard Wine distribution includes quite a few different
executables, libraries, and configuration files. All of these
must be set up properly for Wine to work well. This chapter
will guide you through the necessary steps to get Wine
installed on your system.
</para>
<para>
If you are running a distribution of Linux that uses packages
to keep track of installed software, you may be in luck: A
prepackaged version of Wine may already exist for your system.
The first three sections will tell you how to find the latest
Wine packages and get them installed. You should be careful,
though, about mixing packages between different distributions,
and even from different versions of the same distribution.
Often a package will only work on the distribution it's
compiled for. We'll cover <link
linkend="getting-dist-debian">Debian</link>, <link
linkend="getting-dist-redhat">Redhat</link>, and <link
linkend="getting-dist-other">other</link> distributions.
</para>
<para>
If you're not lucky enough to have an available package for
your operating system, or if you'd prefer a newer version of
Wine than already exists as a package, you may have to
download the Wine source code and compile it yourself on your
own machine. Don't worry, it's not too hard to do this,
especially with the many helpful tools that come with Wine.
You don't need any programming experience to compile and
install Wine, although it might be nice to have some minor
UNIX administrative skill. We'll cover how to retrieve and
compile the official source releases from the <link
linkend="getting-source-ftp">FTP archives</link>, and also how
to get the cutting edge up-to-the-minute fresh Wine source
code from <link linkend="getting-source-cvs">CVS (Concurrent
Versions System)</link>. Both processes of source code
installation are similar, and once you master one, you should
have no trouble dealing with the other one.
</para>
<para>
Finally, you may someday need to know how to apply a source
code patch to your version of Wine. Perhaps you've uncovered
a bug in Wine, reported it to the <ulink
url="mailto:wine-devel@winehq.com">Wine mailing list</ulink>,
and received a patch from a developer to hopefully fix the
bug. The last section in this chapter will show you how to
<link linkend="getting-upgrading">safely apply the
patch</link> and revert it if the patch doesn't work.
</para>
</sect1>
<sect1 id="getting-dist-debian">
<title>Getting Wine for a Debian System</title>
<para>
In most cases on a Debian system, you can install Wine with a
single command, as root:
</para>
<screen>
# apt-get install wine
</screen>
<para>
<command>apt-get</command> will connect to a Debian archive
across the Internet (thus, you must be online), then download
the Wine package and install it on your system. End of story.
</para>
<para>
Of course, Debian's pre-packaged version of Wine may not be the
most recent release. If you are running the stable version of
Debian, you may be able to get a slightly newer version of Wine
by grabbing the package from the unstable distribution, although
this may be a little risky, depending on how far the unstable
distribution has diverged from the stable one. You can find a
list of Wine binary packages for the various Debian releases
using the
<ulink url="http://cgi.debian.org/cgi-bin/search_packages.pl?keywords=wine&amp;searchon=names&amp;version=all&amp;release=all">
package search engine</ulink> at <ulink url="http://www.debian.org">
www.debian.org</ulink>.
</para>
<para>
To install a package that's not part of your distribution, you
must use <command>dpkg</command> instead of
<command>apt-get</command>. Since <command>dpkg</command>
doesn't download the file for you, you must do it yourself.
Follow the link on the package search engine to the desired
package, then click on the <guibutton>Go To Download
Page</guibutton> button and follow the instructions. Save the
file to your hard drive, then run <command>dpkg</command> on it.
For example, if you saved the file to your home directory, you
might perform the following actions to install it:
</para>
<screen>
$ su -
<emphasis>&lt;Type in root password></emphasis>
# cd /home/user
# dpkg -i wine_0.0.20000109-3.deb
</screen>
<para>
You may also want to install the
<systemitem>wine-doc</systemitem> package, and if you are
using Wine from the 2.3 distribution (Woody), the
<systemitem>wine-utils</systemitem> package as well.
</para>
</sect1>
<sect1 id="getting-dist-redhat">
<title>Getting Wine for a Redhat System</title>
<para>
Redhat/RPM users can use <ulink url="http://rpmfind.net/linux/RPM/">
rpmfind.net</ulink> to track down available Wine RPM binaries.
<ulink url="http://rpmfind.net/linux/RPM/WByName.html"> This
page</ulink> contains a list of all rpmfind packages that start with
the letter "W", including a few Wine packages
</para>
<!-- *** Should really flesh this out more! Any Redhat-running
*** volunteers?
-->
</sect1>
<sect1 id="getting-dist-other">
<title>Getting Wine for Other Distributions</title>
<para>
The first place you should look if your system isn't Debian or
Redhat is the <ulink
url="http://www.winehq.com/download.html">WineHQ Download
Page</ulink>. This page lists many assorted archives of
binary (precompiled) Wine files.
</para>
<para>
<ulink url="http://ftpsearch.lycos.com/?form=medium">
Lycos FTPSearch</ulink> is another useful resource for
tracking down miscellaneous distribution packages.
</para>
<!-- *** Add other distributions, e.g., Mandrake, SUSE, Slackware *** -->
</sect1>
<sect1 id="getting-source-ftp">
<title>Getting Wine Source Code from the FTP Archive</title>
<para>
If the version of Wine you want does not exist in package form,
you can download the source code yourself and compile it on your
machine. Although this might seem a little intimidating at
first if you've never done it, you'll find that it'll often go
quite smoothly, especially on the newer Linux distributions.
</para>
<para>
The safest way to grab the source is from one of the official
FTP archives. An up to date listing is in the <ulink
url="http://www.winehq.com/source/ANNOUNCE">ANNOUNCE </ulink>
file in the Wine distribution (which you would have if you
already downloaded it). Here is a (possibly out of date) list
of FTP servers carrying Wine:
</para>
<itemizedlist>
<listitem>
<para>
<ulink url="ftp://metalab.unc.edu/pub/Linux/ALPHA/wine/development/">
ftp://metalab.unc.edu/pub/Linux/ALPHA/wine/development/
</ulink>
</para>
</listitem>
<listitem>
<para>
<ulink url="ftp://tsx-11.mit.edu/pub/linux/ALPHA/Wine/development/">
ftp://tsx-11.mit.edu/pub/linux/ALPHA/Wine/development/
</ulink>
</para>
</listitem>
<listitem>
<para>
<ulink url="ftp://ftp.infomagic.com/pub/mirrors/linux/sunsite/ALPHA/wine/development/">
ftp://ftp.infomagic.com/pub/mirrors/linux/sunsite/ALPHA/wine/development/
</ulink>
</para>
</listitem>
<listitem>
<para>
<ulink url="ftp://orcus.progsoc.uts.edu.au/pub/Wine/development/">
ftp://orcus.progsoc.uts.edu.au/pub/Wine/development/
</ulink>
</para>
</listitem>
</itemizedlist>
<para>
The official releases are tagged by date with the format
"Wine-YYYYMMDD.tar.gz". Your best bet is to grab the latest
one.
</para>
<para>
FIXME: Explain how to un-tar, compile, and install Wine from a tarball.
</para>
<para></para>
</sect1>
<sect1 id="getting-source-cvs">
<title>Getting Wine Source Code from CVS</title>
<para>
The official web page for Wine CVS is
<ulink url="http://www.winehq.com/dev.html">
http://www.winehq.com/dev.html</ulink>.
</para>
<para>
First, you need to get a copy of the latest Wine sources
using CVS. You can tell it where to find the source tree by
setting the <envar>CVSROOT</envar> environment variable. You
also have to log in anonymously to the wine CVS server. In
<command>bash</command>, it might look something like this:
</para>
<screen>
$ export CVSROOT=:pserver:cvs@cvs.winehq.com:/home/wine
$ cvs login
Password: cvs
$ cvs checkout wine
</screen>
<para>
That'll pull down the entire Wine source tree from
winehq.com and place it in the current directory (actually
in the 'wine' subdirectory). CVS has a million command line
parameters, so there are many ways to pull down files, from
anywhere in the revision history. Later, you can grab just
the updates:
</para>
<screen>
$ cvs -dP update
</screen>
<para>
<command>cvs update</command> works from inside the source tree.
You don't need the <envar>CVSROOT</envar> environment variable
to run it either. You just have to be inside the source tree.
The <parameter>-d</parameter> and <parameter>-P</parameter>
options make sure your local Wine tree directory structure stays
in sync with the remote repository.
</para>
<para>
After you've made changes, you can create a patch with
<command>cvs diff -u</command>, which sends output to stdout
(the <parameter>-u</parameter> controls the format of the
patch). So, to create an <filename>my_patch.diff</filename>
file, you would do this:
</para>
<screen>
$ cvs diff -u > my_patch.diff
</screen>
<para>
You can call <command>cvs diff</command> from anywhere in the
tree (just like <command>cvs update</command>), and it will
always grab recursively from that point. You can also specify
single files or subdirectories:
</para>
<screen>
$ cvs diff -u dlls/winaspi > my_aspi_patch.diff
</screen>
<para>
Experiment around a little. It's fairly intuitive.
</para>
</sect1>
<sect1 id="getting-upgrading">
<title>Upgrading Wine with a Patch</title>
<para>
If you have the Wine source code, as opposed to a binary
distribution, you have the option of applying patches to the
source tree to fix bugs and add experimental features.
Perhaps you've found a bug, reported it to the <ulink
url="mailto:wine-devel@winehq.com">Wine mailing list</ulink>,
and received a patch file to fix the bug. You can apply the
patch with the <command>patch</command> command, which takes a
streamed patch from <filename>stdin</filename>:
</para>
<screen>
$ cd wine
$ patch -p0 < ../patch_to_apply.diff
</screen>
<para>
To remove the patch, use the <parameter>-R</parameter> option:
</para>
<screen>
$ patch -p0 -R < ../patch_to_apply.diff
</screen>
<para>
If you want to do a test run to see if the patch will apply
successfully (e.g., if the patch was created from an older or
newer version of the tree), you can use the
<parameter>--dry-run</parameter> parameter to run the patch
without writing to any files:
</para>
<screen>
$ patch -p0 --dry-run < ../patch_to_apply.diff
</screen>
<para>
<command>patch</command> is pretty smart about extracting
patches from the middle of a file, so if you save an email with
an inlined patch to a file on your hard drive, you can invoke
patch on it without stripping out the email headers and other
text. <command>patch</command> ignores everything that doesn't
look like a patch.
</para>
<para>
FIXME: Go into more depth about the -p0 option...
</para>
</sect1>
</chapter>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-parent-document:("wine-doc.sgml" "set" "book" "chapter" "")
End:
-->
......@@ -5,12 +5,13 @@
<title>Adding New Languages</title>
<para>
written by Morten Welinder, January 1996.
Written by &name-morten-welinder; <email>&email-morten-welinder;</email>,
January 1996.
</para>
<itemizedlist>
<listitem>
<para>Thereafter revised Februari 1999 by Klaas van Gend</para>
<para>Thereafter revised February 1999 by Klaas van Gend</para>
</listitem>
<listitem>
<para>Revised again May 23, 1999, Klaas van Gend</para>
......@@ -37,6 +38,7 @@
<member>Japanese</member>
<member>Romanian</member>
<member>Croatian</member>
<member>Slovak</member>
<member>Turkish</member>
<member>Slovanian</member>
</simplelist>
......@@ -196,6 +198,6 @@
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-parent-document:("wine-doc.sgml" "book" "part" "chapter" "")
sgml-parent-document:("wine-doc.sgml" "set" "book" "part" "chapter" "")
End:
-->
......@@ -6,7 +6,7 @@
<title>Builtin DLLs</title>
<para>
written by &lt;juergen.schmied@metronet.de>
Written by &name-juergen-schmied; <email>&email-juergen-schmied;</email>
</para>
<para>
(Extracted from <filename>wine/documentation/internal-dll</filename>)
......@@ -195,7 +195,7 @@ WORD cmd;
<title>File Handles</title>
<para>
written by (???)
Written by (???)
</para>
<para>
(Extracted from <filename>wine/documentation/filehandles</filename>)
......@@ -260,7 +260,7 @@ WORD cmd;
<title>Doing A Hardware Trace In Wine</title>
<para>
written by Jonathan Buzzard &lt;jab@hex.prestel.co.uk>
Written by &name-jonathan-buzzard; <email>&email-jonathan-buzzard;</email>
</para>
<para>
(Extracted from <filename>wine/documentation/ioport-trace-hints</filename>)
......@@ -530,6 +530,6 @@ EOF
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-parent-document:("wine-doc.sgml" "book" "part" "chapter" "")
sgml-parent-document:("wine-doc.sgml" "set" "book" "part" "chapter" "")
End:
-->
<chapter id="installing">
<title>Installing Wine</title>
<title>Installing/compiling Wine</title>
<para>How to install Wine...</para>
<sect1 id="replace-windows">
<sect1 id="replace-windows" xreflabel="--Installing Section--">
<title>WWN #52 Feature: Replacing Windows</title>
<para>
Written by Ove Kåven <email>ovek@winehq.com</email>
Written by &name-ove-kaaven; <email>&email-ove-kaaven;</email>
</para>
<sect2>
......@@ -197,7 +198,7 @@ Filesystem=win95
<sect1 id="no-windows">
<title>Installing Wine Without Windows</title>
<para>
written by ???
Written by &name-james-juran; <email>&email-james-juran;</email>
</para>
<para>
(Extracted from <filename>wine/documentation/no-windows</filename>)
......@@ -206,7 +207,7 @@ Filesystem=win95
<para>
A major goal of Wine is to allow users to run Windows programs
without having to install Windows on their machine. Wine
implements the functionality of the main DLL's usually
implements the functionality of the main DLLs usually
provided with Windows. Therefore, once Wine is finished, you
will not need to have windows installed to use Wine.
</para>
......@@ -259,7 +260,7 @@ Filesystem=win95
<para>
Because Wine is not yet complete, some programs will work
better with native Windows DLL's than with Wine's
better with native Windows DLLs than with Wine's
replacements. Wine has been designed to make this possible.
Here are some tips by Juergen Schmied (and others) on how to
proceed. This assumes that your
......@@ -275,7 +276,7 @@ Filesystem=win95
<para>
Run the application with <parameter>--debugmsg
+module,+file</parameter> to find out which files are
needed. Copy the required DLL's one by one to the
needed. Copy the required DLLs one by one to the
<filename>C:\windows\system</filename> directory. Do not
copy KERNEL/KERNEL32, GDI/GDI32, or USER/USER32. These
implement the core functionality of the Windows API, and
......@@ -288,13 +289,13 @@ Filesystem=win95
<filename>wine.conf</filename> or
<filename>.winerc</filename> to specify
<quote>native</quote> before <quote>builtin</quote> for
the Windows DLL's you want to use. For more information
the Windows DLLs you want to use. For more information
about this, see the Wine manpage.
</para>
</listitem>
<listitem>
<para>
Note that some network DLL's are not needed even though
Note that some network DLLs are not needed even though
Wine is looking for them. The Windows
<filename>MPR.DLL</filename> currently does not work; you
must use the internal implementation.
......@@ -303,7 +304,7 @@ Filesystem=win95
<listitem>
<para>
Copy SHELL/SHELL32 and COMDLG/COMDLG32 COMMCTRL/COMCTL32
only as pairs to your Wine directory (these DLL's are
only as pairs to your Wine directory (these DLLs are
<quote>clean</quote> to use). Make sure you have these
specified in the <quote>[DllPairs]</quote> section of
<filename>wine.conf</filename> or .winerc.
......@@ -311,18 +312,18 @@ Filesystem=win95
</listitem>
<listitem>
<para>
Be consistent: Use only DLL's from the same Windows version
Be consistent: Use only DLLs from the same Windows version
together.
</para>
</listitem>
<listitem>
<para>
Put <filename>regedit.exe</filename> in the
<filename>C:\windows</filename> directory
(<application>office95</application> imports a
<filename>*.reg</filename> file when it runs with a empty
<filename>C:\windows</filename> directory.
(<application>Office 95</application> imports a
<filename>*.reg</filename> file when it runs with an empty
registry, don't know about
<application>office97</application>).
<application>Office 97</application>).
</para>
</listitem>
<listitem>
......@@ -338,7 +339,7 @@ Filesystem=win95
<sect1 id="vfat">
<title>Dealing With FAT/VFAT Partitions</title>
<para>
written by Steven Elliott (elliotsl@mindspring.com)
Written by &name-steven-elliott; <email>&email-steven-elliott;</email>
</para>
<para>
(Extracted from <filename>wine/documentation/linux-fat-permissions</filename>)
......@@ -381,11 +382,11 @@ Type=hd
</para>
<para>
Most modern Linux distributions either detect or allow
existing FAT file systems to be configured so that can be
existing FAT file systems to be configured so that they can be
mounted, in a location such as <filename>/c</filename>,
either persistently (on bootup) or on an as needed basis. In
either case, by default, the permissions will probably be
configured so that they look something like:
configured so that they look like:
</para>
<screen>
<prompt>~></prompt><userinput>cd /c</userinput>
......@@ -403,7 +404,7 @@ drwxr-xr-x 41 root root 16384 Dec 30 1998 windows</computeroutput>
filesystem.
</para>
<para>
There three major approaches to overcoming the restrictive
There are three major approaches to overcoming the restrictive
permissions mentioned in the previous paragraph:
</para>
<orderedlist>
......@@ -524,7 +525,7 @@ drwxrwxr-x 41 sle sle 16384 Dec 30 1998 windows</computeroutput>
Shadowing provides a finer granularity of control. Parts of
the original FAT filesystem can be copied so that the
application can safely work with those copied parts while
the application continue to directly read the remaining
the application continues to directly read the remaining
parts. This is done with symbolic links. For example,
consider a system where an application named
<application>AnApp</application> must be able to read and
......@@ -558,7 +559,8 @@ drwxrwxr-x 41 sle sle 16384 Dec 30 1998 windows</computeroutput>
<sect1 id="scsi-support">
<title>SCSI Support</title>
<para>
written by Bruce Milner; Additions by Andreas Mohr
Written by &name-bruce-milner; <email>&email-bruce-milner;</email>;
Additions by &name-andreas-mohr; <email>&email-andreas-mohr;</email>
</para>
<para>
(Extracted from <filename>wine/documentation/aspi</filename>)
......@@ -586,18 +588,19 @@ THIS MAY TRASH YOUR SYSTEM IF USED CORRECTLY
to it to the SCSI bus.
</para>
<para>
If you use the wrong scsi device in your setup file, you can send
If you use the wrong SCSI device in your setup file, you can send
completely bogus commands to the wrong device - An example would be
formatting your hard drives (assuming the device gave you permission -
if you're running as root, all bets are off).
</para>
<para>
So please make sure that **all** SCSI devices not needed by the program
So please make sure that <emphasis>all</emphasis> SCSI devices not needed by the program
have their permissions set as restricted as possible !
</para>
<para>
Cookbook for setting up scanner: (At least how mine is to work)
(well, for other devices such as CD burners, MO drives, ..., too)
</para>
<sect2>
......@@ -628,20 +631,27 @@ THIS MAY TRASH YOUR SYSTEM IF USED CORRECTLY
<orderedlist>
<listitem>
<para>
Your scsi card must be supported under linux. This will
not work with an unknown scsi card. Even for cheap'n
Your SCSI card must be supported under linux. This will
not work with an unknown SCSI card. Even for cheap'n
crappy "scanner only" controllers some special Linux
drivers exist on the net.
If you intend to use your IDE device, you need to use the
ide-scsi emulation.
Read
<ulink url="http://www.linuxdoc.org/HOWTO/CD-Writing-HOWTO.html">
http://www.linuxdoc.org/HOWTO/CD-Writing-HOWTO.html</ulink>
for ide-scsi setup instructions.
</para>
</listitem>
<listitem>
<para>
Compile generic scsi drivers into your kernel.
Compile generic SCSI drivers into your kernel.
</para>
</listitem>
<listitem>
<para>
Linux by default uses smaller scsi buffers than Windows.
This seems to be not required any more for newer (2.2.x) kernels:
Linux by default uses smaller SCSI buffers than Windows.
There is a kernel build define <literal>SG_BIG_BUFF</literal> (in
<filename>sg.h</filename>) that is by default set too
low. The SANE project recommends
......@@ -651,9 +661,11 @@ THIS MAY TRASH YOUR SYSTEM IF USED CORRECTLY
</listitem>
<listitem>
<para>
Make the devices for the scanner (generic scsi devices)
- look at the scsi programming how-to for device
numbering.
Make the devices for the scanner (generic SCSI devices)
- look at the SCSI programming HOWTO at
<ulink url="http://www.linuxdoc.org/HOWTO/SCSI-Programming-HOWTO.html">
http://www.linuxdoc.org/HOWTO/SCSI-Programming-HOWTO.html</ulink>
for device numbering.
</para>
</listitem>
<listitem>
......@@ -661,16 +673,17 @@ THIS MAY TRASH YOUR SYSTEM IF USED CORRECTLY
I would recommend making the scanner device writable by
a group. I made a group called
<literal>scanner</literal> and added myself to it.
Running as root increases your risk of sending bad scsi
Running as root increases your risk of sending bad SCSI
commands to the wrong device. With a regular user, you
are better protected.
</para>
</listitem>
<listitem>
<para>
Add a scsi device entry for your particular scanner to
wine.conf. The format is <literal>[scsi
cCtTdD]</literal> where
For Win32 software (WNASPI32), Wine has auto-detection in place.
For Win16 software (WINASPI), you need to add a SCSI device entry
for your particular scanner to wine.conf. The format is
<literal>[scsi cCtTdD]</literal> where
<literal>C=controller</literal>,
<literal>T=target</literal>, <literal>D=LUN</literal>
</para>
......@@ -727,14 +740,14 @@ ipplus.exe &lt;---> (TWAIN INTERFACE) &lt;---> (TWAIN DATA SOURCE . ASPI) -> WIN
</listitem>
<listitem>
<para>
a Fujitsu M2513A MO drive (640MB) using generic scsi
a Fujitsu M2513A MO drive (640MB) using generic SCSI
drivers. Formatting and ejecting worked perfectly.
Thanks to Uwe Bonnes for access to the hardware ! [AM]
</para>
</listitem>
</itemizedlist>
<para>
I make no warranty to the aspi code. It makes my scanner
I make no warranty to the ASPI code. It makes my scanner
work. Your devices may explode. I have no way of determining
this. I take zero responsibility!
</para>
......@@ -746,6 +759,6 @@ ipplus.exe &lt;---> (TWAIN INTERFACE) &lt;---> (TWAIN DATA SOURCE . ASPI) -> WIN
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-parent-document:("wine-doc.sgml" "book" "chapter" "")
sgml-parent-document:("wine-doc.sgml" "set" "book" "chapter" "")
End:
-->
<chapter id="introduction">
<title>Introduction</title>
<sect1 id="what-is-wine">
<title>What is Wine?</title>
<para>
Written by &name-john-sheets; <email>&email-john-sheets;</email>
</para>
<sect2>
<title>Windows and Linux</title>
<!-- general description of wine, what does it do? -->
<para>
Many people have faced the frustration of owning software that
won't run on their computer. With the recent popularity of
Linux, this is happening more and more often because of
differing operating systems. Your Windows software won't run
on Linux, and your Linux software won't run in Windows.
</para>
<para>
A common solution to this problem is to install both operating
systems on the same computer, as a <quote>dual boot</quote>
system. If you want to write a document in MS Word, you can
boot up in Windows; if you want to run the GnuCash, the GNOME
financial application, you can shut down your Windows session
and reboot into Linux. The problem with this is that you
can't do both at the same time. Each time you switch back and
forth between MS Word and GnuCash, you have to reboot again.
This can get tiresome quickly.
</para>
<para>
Life would be so much easier if you could run all your
applications on the same system, regardless of whether they
are written for Windows or for Linux. On Windows, this isn't
really possible.
<footnote>
<para>
Technically, if you have two networked computers, one
running Windows and the other running Linux, and if you
have some sort of X server software running on the Windows
system, you can export Linux applications onto the Windows
system. Unfortunately, most decent win32 X servers are
commercial products, many of which cost quite a lot.
However, this doesn't solve the problem if you only own
one computer system.
</para>
</footnote>
However, Wine makes it possible to run native Windows
applications alongside native Linux applications on a Linux
(or Solaris) system. You can share desktop space between MS
Word and GnuCash, overlapping their windows, iconizing them,
and even running them from the same launcher.
</para>
</sect2>
<sect2>
<title>Emulation versus Native Linking</title>
<!-- emulator vs. Winelib -->
<para>
Wine is a UNIX implementation of the win32 libraries,
written from scratch by hundreds of volunteer developers and
released under an open source license. Anyone can download
and read through the source code, and fix bugs that arise.
The Wine community is full of richly talented programmers
who have spent thousands of hours of personal time on
improving Wine so that it works well with the win32
<firstterm>Applications Programming Interface</firstterm>
(API), and keeps pace with new developments from Microsoft.
</para>
<para>
Wine can run applications in two discrete ways: as
pre-compiled Windows binaries, or as natively compiled X11
(X Window System) applications. The former method uses
emulation to connect a Windows application to the Wine
libraries. You can run your Windows application directly
with the emulator, by installing through Wine or by simply
copying the Windows executables onto your Linux system.
</para>
<para>
The other way to run Windows applications with Wine requires
that you have the source code for the application. Instead
of compiling it with native Windows compilers, you can
compile it with a native Linux compiler --
<command>gcc</command> for example -- and link in the Wine
Libraries as you would with any other native UNIX
application. These natively linked applications are
referred to as Winelib applications.
</para>
<para>
The Wine Users Guide will focus on running precompiled
Windows applications using the Wine emulator.
<ulink url="http://wine.codeweavers.com/docs/winelib-user/">
The Winelib Users Guide</ulink> will cover Winelib
applications.
</para>
<!-- the development model -->
<para>
</para>
</sect2>
</sect1>
<!-- *** Not really useful as is, but may be able to recycle this elsewhere...
<sect1 id="getting-started">
<title>Getting started</title>
<para>
Written by &name-john-sheets; <email>&email-john-sheets;</email>
</para>
<para>
Wine can be pretty intimidating at first. The Wine
distribution consists of over two thousand files and half a
million lines of source code
<footnote>
<para>Crudely calculated from running <command>find . | wc
-l</command> and <command>cat `find . -name "*.c"` | wc
-l</command>, respectively, from a fresh CVS checkout.</para>
</footnote>,
and is probably one of the steepest learning curves in the
open source world. This chapter will give you a crash course
in the important topics you need to know to get started with
running Wine applications.
</para>
</sect1>
-->
<sect1 id="wine-stats">
<title>Wine Requirements and Features</title>
<para>
Written by &name-andreas-mohr; <email>&email-andreas-mohr;</email>
</para>
<sect2 id="system-requirements">
<title>System requirements</title>
<para>
In order to run Wine, you need the following:
</para>
<para>
<itemizedlist>
<listitem>
<para>
a computer ;-) Wine: only PCs >= i386 are supported at
the moment. Winelib: other platforms might be
supported, but can be tricky.
</para>
</listitem>
<listitem>
<para>
a UNIX-like operating system such as Linux, *BSD,
Solaris x86
</para>
</listitem>
<listitem>
<para>
>= 16MB of RAM. Everything below is pretty much
unusable. >= 64 MB is needed for a "good" execution.
</para>
</listitem>
<listitem>
<para>
an X11 window system (XFree86 etc.). Wine is prepared
for other graphics display drivers, but writing
support is not too easy. The text console display
driver is nearly usable.
</para>
</listitem>
</itemizedlist>
</para>
</sect2>
<sect2 id="wine-capabilities">
<title>Wine capabilities</title>
<para>
Now that you hopefully managed to fulfill the requirements
mentioned above, we tell you what Wine is able to do/support:
</para>
<para>
<itemizedlist>
<listitem>
<para>
Support for executing DOS, Win 3.x and Win9x/NT/Win2000
programs (most of Win32's controls are supported)
</para>
</listitem>
<listitem>
<para>
Optional use of external vendor DLLs (e.g. original
Windows DLLs)
</para>
</listitem>
<listitem>
<para>
X11-based graphics display (remote display to any X
terminal possible), text mode console
</para>
</listitem>
<listitem>
<para>
Desktop-in-a-box or mixable windows
</para>
</listitem>
<listitem>
<para>
Pretty advanced DirectX support for games
</para>
</listitem>
<listitem>
<para>
Good support for sound, alternative input devices
</para>
</listitem>
<listitem>
<para>
Printing: supports native Win16 printer drivers,
Internal PostScript driver
</para>
</listitem>
<listitem>
<para>
Modems, serial devices are supported
</para>
</listitem>
<listitem>
<para>
Winsock TCP/IP networking
</para>
</listitem>
<listitem>
<para>
ASPI interface (SCSI) support for scanners, CD writers,
...
</para>
</listitem>
<listitem>
<para>
Unicode support, relatively advanced language support
</para>
</listitem>
<listitem>
<para>
Wine debugger and configurable trace logging messages
</para>
</listitem>
</itemizedlist>
</para>
</sect2>
</sect1>
</chapter>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-parent-document:("wine-doc.sgml" "set" "book" "chapter" "")
End:
-->
<chapter id="ole">
<title>COM/OLE in Wine</title>
<sect1 id="ole-architecture">
<title>COM/OLE Architecture in Wine</title>
<para>
The section goes into detail about how COM/OLE2 are
implemented in Wine.
</para>
</sect1>
<sect1 id="ole-binary">
<title>Using Binary OLE components in Wine</title>
<para>
This section describes how to import pre-compiled COM/OLE
components...
</para>
</sect1>
<sect1 id="com-writing">
<title>Writing OLE Components for Wine</title>
<para>
Based on the comments in <filename>wine/include/wine/obj_base.h</filename>.
</para>
<para>
This section describes how to create your own natively
compiled COM/OLE components.
</para>
<sect2>
<title>Macros to define a COM interface</title>
<para>
The goal of the following set of definitions is to provide a
way to use the same header file definitions to provide both
a C interface and a C++ object oriented interface to COM
interfaces. The type of interface is selected automatically
depending on the language but it is always possible to get
the C interface in C++ by defining CINTERFACE.
</para>
<para>
It is based on the following assumptions:
</para>
<itemizedlist>
<listitem>
<para>
all COM interfaces derive from IUnknown, this should not
be a problem.
</para>
</listitem>
<listitem>
<para>
the header file only defines the interface, the actual
fields are defined separately in the C file implementing
the interface.
</para>
</listitem>
</itemizedlist>
<para>
The natural approach to this problem would be to make sure
we get a C++ class and virtual methods in C++ and a
structure with a table of pointer to functions in C.
Unfortunately the layout of the virtual table is compiler
specific, the layout of g++ virtual tables is not the same
as that of an egcs virtual table which is not the same as
that generated by Visual C+. There are workarounds to make
the virtual tables compatible via padding but unfortunately
the one which is imposed to the WINE emulator by the Windows
binaries, i.e. the Visual C++ one, is the most compact of
all.
</para>
<para>
So the solution I finally adopted does not use virtual
tables. Instead I use inline non virtual methods that
dereference the method pointer themselves and perform the
call.
</para>
<para>
Let's take Direct3D as an example:
</para>
<programlisting>#define ICOM_INTERFACE IDirect3D
#define IDirect3D_METHODS \
ICOM_METHOD1(HRESULT,Initialize, REFIID,) \
ICOM_METHOD2(HRESULT,EnumDevices, LPD3DENUMDEVICESCALLBACK,, LPVOID,) \
ICOM_METHOD2(HRESULT,CreateLight, LPDIRECT3DLIGHT*,, IUnknown*,) \
ICOM_METHOD2(HRESULT,CreateMaterial,LPDIRECT3DMATERIAL*,, IUnknown*,) \
ICOM_METHOD2(HRESULT,CreateViewport,LPDIRECT3DVIEWPORT*,, IUnknown*,) \
ICOM_METHOD2(HRESULT,FindDevice, LPD3DFINDDEVICESEARCH,, LPD3DFINDDEVICERESULT,)
#define IDirect3D_IMETHODS \
IUnknown_IMETHODS \
IDirect3D_METHODS
ICOM_DEFINE(IDirect3D,IUnknown)
#undef ICOM_INTERFACE
#ifdef ICOM_CINTERFACE
// *** IUnknown methods *** //
#define IDirect3D_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b)
#define IDirect3D_AddRef(p) ICOM_CALL (AddRef,p)
#define IDirect3D_Release(p) ICOM_CALL (Release,p)
// *** IDirect3D methods *** //
#define IDirect3D_Initialize(p,a) ICOM_CALL1(Initialize,p,a)
#define IDirect3D_EnumDevices(p,a,b) ICOM_CALL2(EnumDevice,p,a,b)
#define IDirect3D_CreateLight(p,a,b) ICOM_CALL2(CreateLight,p,a,b)
#define IDirect3D_CreateMaterial(p,a,b) ICOM_CALL2(CreateMaterial,p,a,b)
#define IDirect3D_CreateViewport(p,a,b) ICOM_CALL2(CreateViewport,p,a,b)
#define IDirect3D_FindDevice(p,a,b) ICOM_CALL2(FindDevice,p,a,b)
#endif</programlisting>
<para>
Comments:
</para>
<para>
The ICOM_INTERFACE macro is used in the ICOM_METHOD macros
to define the type of the 'this' pointer. Defining this
macro here saves us the trouble of having to repeat the
interface name everywhere. Note however that because of the
way macros work, a macro like ICOM_METHOD1 cannot use
'ICOM_INTERFACE##_VTABLE' because this would give
'ICOM_INTERFACE_VTABLE' and not 'IDirect3D_VTABLE'.
</para>
<para>
ICOM_METHODS defines the methods specific to this
interface. It is then aggregated with the inherited methods
to form ICOM_IMETHODS.
</para>
<para>
ICOM_IMETHODS defines the list of methods that are
inheritable from this interface. It must be written manually
(rather than using a macro to generate the equivalent code)
to avoid macro recursion (which compilers don't like).
</para>
<para>
The ICOM_DEFINE finally declares all the structures
necessary for the interface. We have to explicitly use the
interface name for macro expansion reasons again. Inherited
methods are inherited in C by using the IDirect3D_METHODS
macro and the parent's Xxx_IMETHODS macro. In C++ we need
only use the IDirect3D_METHODS since method inheritance is
taken care of by the language.
</para>
<para>
In C++ the ICOM_METHOD macros generate a function prototype
and a call to a function pointer method. This means using
once 't1 p1, t2 p2, ...' and once 'p1, p2' without the
types. The only way I found to handle this is to have one
ICOM_METHOD macro per number of parameters and to have it
take only the type information (with const if necessary) as
parameters. The 'undef ICOM_INTERFACE' is here to remind
you that using ICOM_INTERFACE in the following macros will
not work. This time it's because the ICOM_CALL macro
expansion is done only once the 'IDirect3D_Xxx' macro is
expanded. And by that time ICOM_INTERFACE will be long gone
anyway.
</para>
<para>
You may have noticed the double commas after each parameter
type. This allows you to put the name of that parameter
which I think is good for documentation. It is not required
and since I did not know what to put there for this example
(I could only find doc about IDirect3D2), I left them blank.
</para>
<para>
Finally the set of 'IDirect3D_Xxx' macros is a standard set
of macros defined to ease access to the interface methods in
C. Unfortunately I don't see any way to avoid having to
duplicate the inherited method definitions there. This time
I could have used a trick to use only one macro whatever the
number of parameters but I prefered to have it work the same
way as above.
</para>
<para>
You probably have noticed that we don't define the fields we
need to actually implement this interface: reference count,
pointer to other resources and miscellaneous fields. That's
because these interfaces are just that: interfaces. They may
be implemented more than once, in different contexts and
sometimes not even in Wine. Thus it would not make sense to
impose that the interface contains some specific fields.
</para>
</sect2>
<sect2>
<title>Bindings in C</title>
<para>
In C this gives:
</para>
<programlisting>typedef struct IDirect3DVtbl IDirect3DVtbl;
struct IDirect3D {
IDirect3DVtbl* lpVtbl;
};
struct IDirect3DVtbl {
HRESULT (*fnQueryInterface)(IDirect3D* me, REFIID riid, LPVOID* ppvObj);
ULONG (*fnAddRef)(IDirect3D* me);
ULONG (*fnRelease)(IDirect3D* me);
HRESULT (*fnInitialize)(IDirect3D* me, REFIID a);
HRESULT (*fnEnumDevices)(IDirect3D* me, LPD3DENUMDEVICESCALLBACK a, LPVOID b);
HRESULT (*fnCreateLight)(IDirect3D* me, LPDIRECT3DLIGHT* a, IUnknown* b);
HRESULT (*fnCreateMaterial)(IDirect3D* me, LPDIRECT3DMATERIAL* a, IUnknown* b);
HRESULT (*fnCreateViewport)(IDirect3D* me, LPDIRECT3DVIEWPORT* a, IUnknown* b);
HRESULT (*fnFindDevice)(IDirect3D* me, LPD3DFINDDEVICESEARCH a, LPD3DFINDDEVICERESULT b);
};
#ifdef ICOM_CINTERFACE
// *** IUnknown methods *** //
#define IDirect3D_QueryInterface(p,a,b) (p)->lpVtbl->fnQueryInterface(p,a,b)
#define IDirect3D_AddRef(p) (p)->lpVtbl->fnAddRef(p)
#define IDirect3D_Release(p) (p)->lpVtbl->fnRelease(p)
// *** IDirect3D methods *** //
#define IDirect3D_Initialize(p,a) (p)->lpVtbl->fnInitialize(p,a)
#define IDirect3D_EnumDevices(p,a,b) (p)->lpVtbl->fnEnumDevice(p,a,b)
#define IDirect3D_CreateLight(p,a,b) (p)->lpVtbl->fnCreateLight(p,a,b)
#define IDirect3D_CreateMaterial(p,a,b) (p)->lpVtbl->fnCreateMaterial(p,a,b)
#define IDirect3D_CreateViewport(p,a,b) (p)->lpVtbl->fnCreateViewport(p,a,b)
#define IDirect3D_FindDevice(p,a,b) (p)->lpVtbl->fnFindDevice(p,a,b)
#endif</programlisting>
<para>
Comments:
</para>
<para>
IDirect3D only contains a pointer to the IDirect3D
virtual/jump table. This is the only thing the user needs to
know to use the interface. Of course the structure we will
define to implement this interface will have more fields but
the first one will match this pointer.
</para>
<para>
The code generated by ICOM_DEFINE defines both the structure
representing the interface and the structure for the jump
table. ICOM_DEFINE uses the parent's Xxx_IMETHODS macro to
automatically repeat the prototypes of all the inherited
methods and then uses IDirect3D_METHODS to define the
IDirect3D methods.
</para>
<para>
Each method is declared as a pointer to function field in
the jump table. The implementation will fill this jump table
with appropriate values, probably using a static variable,
and initialize the lpVtbl field to point to this variable.
</para>
<para>
The IDirect3D_Xxx macros then just derefence the lpVtbl
pointer and use the function pointer corresponding to the
macro name. This emulates the behavior of a virtual table
and should be just as fast.
</para>
<para>
This C code should be quite compatible with the Windows
headers both for code that uses COM interfaces and for code
implementing a COM interface.
</para>
</sect2>
<sect2>
<title>Bindings in C++</title>
<para>
And in C++ (with gcc's g++):
</para>
<programlisting>typedef struct IDirect3D: public IUnknown {
private: HRESULT (*fnInitialize)(IDirect3D* me, REFIID a);
public: inline HRESULT Initialize(REFIID a) { return ((IDirect3D*)t.lpVtbl)->fnInitialize(this,a); };
private: HRESULT (*fnEnumDevices)(IDirect3D* me, LPD3DENUMDEVICESCALLBACK a, LPVOID b);
public: inline HRESULT EnumDevices(LPD3DENUMDEVICESCALLBACK a, LPVOID b)
{ return ((IDirect3D*)t.lpVtbl)->fnEnumDevices(this,a,b); };
private: HRESULT (*fnCreateLight)(IDirect3D* me, LPDIRECT3DLIGHT* a, IUnknown* b);
public: inline HRESULT CreateLight(LPDIRECT3DLIGHT* a, IUnknown* b)
{ return ((IDirect3D*)t.lpVtbl)->fnCreateLight(this,a,b); };
private: HRESULT (*fnCreateMaterial)(IDirect3D* me, LPDIRECT3DMATERIAL* a, IUnknown* b);
public: inline HRESULT CreateMaterial(LPDIRECT3DMATERIAL* a, IUnknown* b)
{ return ((IDirect3D*)t.lpVtbl)->fnCreateMaterial(this,a,b); };
private: HRESULT (*fnCreateViewport)(IDirect3D* me, LPDIRECT3DVIEWPORT* a, IUnknown* b);
public: inline HRESULT CreateViewport(LPDIRECT3DVIEWPORT* a, IUnknown* b)
{ return ((IDirect3D*)t.lpVtbl)->fnCreateViewport(this,a,b); };
private: HRESULT (*fnFindDevice)(IDirect3D* me, LPD3DFINDDEVICESEARCH a, LPD3DFINDDEVICERESULT b);
public: inline HRESULT FindDevice(LPD3DFINDDEVICESEARCH a, LPD3DFINDDEVICERESULT b)
{ return ((IDirect3D*)t.lpVtbl)->fnFindDevice(this,a,b); };
};</programlisting>
<para>
Comments:
</para>
<para>
In C++ IDirect3D does double duty as both the virtual/jump
table and as the interface definition. The reason for this
is to avoid having to duplicate the mehod definitions: once
to have the function pointers in the jump table and once to
have the methods in the interface class. Here one macro can
generate both. This means though that the first pointer,
t.lpVtbl defined in IUnknown, must be interpreted as the
jump table pointer if we interpret the structure as the
interface class, and as the function pointer to the
QueryInterface method, t.fnQueryInterface, if we interpret
the structure as the jump table. Fortunately this gymnastic
is entirely taken care of in the header of IUnknown.
</para>
<para>
Of course in C++ we use inheritance so that we don't have to
duplicate the method definitions.
</para>
<para>
Since IDirect3D does double duty, each ICOM_METHOD macro
defines both a function pointer and a non-virtual inline
method which dereferences it and calls it. This way this
method behaves just like a virtual method but does not
create a true C++ virtual table which would break the
structure layout. If you look at the implementation of these
methods you'll notice that they would not work for void
functions. We have to return something and fortunately this
seems to be what all the COM methods do (otherwise we would
need another set of macros).
</para>
<para>
Note how the ICOM_METHOD generates both function prototypes
mixing types and formal parameter names and the method
invocation using only the formal parameter name. This is the
reason why we need different macros to handle different
numbers of parameters.
</para>
<para>
Finally there is no IDirect3D_Xxx macro. These are not
needed in C++ unless the CINTERFACE macro is defined in
which case we would not be here.
</para>
<para>
This C++ code works well for code that just uses COM
interfaces. But it will not work with C++ code implement a
COM interface. That's because such code assumes the
interface methods are declared as virtual C++ methods which
is not the case here.
</para>
</sect2>
<sect2>
<title>Implementing a COM interface.</title>
<para>
This continues the above example. This example assumes that
the implementation is in C.
</para>
<programlisting>typedef struct _IDirect3D {
void* lpVtbl;
// ...
} _IDirect3D;
static ICOM_VTABLE(IDirect3D) d3dvt;
// implement the IDirect3D methods here
int IDirect3D_fnQueryInterface(IDirect3D* me)
{
ICOM_THIS(IDirect3D,me);
// ...
}
// ...
static ICOM_VTABLE(IDirect3D) d3dvt = {
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
IDirect3D_fnQueryInterface,
IDirect3D_fnAdd,
IDirect3D_fnAdd2,
IDirect3D_fnInitialize,
IDirect3D_fnSetWidth
};</programlisting>
<para>
Comments:
</para>
<para>
We first define what the interface really contains. This is
the _IDirect3D structure. The first field must of course be
the virtual table pointer. Everything else is free.
</para>
<para>
Then we predeclare our static virtual table variable, we
will need its address in some methods to initialize the
virtual table pointer of the returned interface objects.
</para>
<para>
Then we implement the interface methods. To match what has
been declared in the header file they must take a pointer to
a IDirect3D structure and we must cast it to an _IDirect3D
so that we can manipulate the fields. This is performed by
the ICOM_THIS macro.
</para>
<para>
Finally we initialize the virtual table.
</para>
</sect2>
</sect1>
</chapter>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-parent-document:("wine-doc.sgml" "set" "book" "part" "chapter" "")
End:
-->
......@@ -2,14 +2,15 @@
<title>Wine and OpenGL</title>
<para>
written by Lionel Ulmer &lt;lionel.ulmer@free.fr>, last modification : 2000/06/13
Written by &name-lionel-ulmer; <email>&email-lionel-ulmer;</email>,
last modification : 2000/06/13
</para>
<para>
(Extracted from <filename>wine/documentation/opengl</filename>)
</para>
<sect1 id="opengl-required">
<title>I What is needed to have OpenGL support in Wine</title>
<title>What is needed to have OpenGL support in Wine</title>
<para>
Basically, if you have a Linux OpenGL ABI compliant libGL
......@@ -29,7 +30,7 @@
</para>
<sect2>
<title>I.1 Header files</title>
<title>Header files</title>
<para>
The needed header files to build OpenGL support in Wine are :
......@@ -67,7 +68,7 @@
</sect2>
<sect2>
<title>I.2 OpenGL library thread-safety</title>
<title>OpenGL library thread-safety</title>
<para>
After that, the script checks if the OpenGL library relies
......@@ -96,7 +97,7 @@
</sect2>
<sect2>
<title>I.3 OpenGL library itself</title>
<title>OpenGL library itself</title>
<para>
To check for the presence of 'libGL' on the system, the
......@@ -107,7 +108,7 @@
</sect2>
<sect2>
<title>I.4 glXGetProcAddressARB function</title>
<title>glXGetProcAddressARB function</title>
<para>
The core of Wine's OpenGL implementation (at least for all
......@@ -130,7 +131,7 @@
</sect1>
<sect1 id="opengl-configure">
<title>II How to configure</title>
<title>How to configure</title>
<para>
Configuration is quite easy : once OpenGL support has been
......@@ -156,7 +157,7 @@ DesktopDoubleBuffered = Y
</sect1>
<sect1 id="opengl-works">
<title>III How it all works</title>
<title>How it all works</title>
<para>
The core OpenGL function calls are the same between Windows
......@@ -191,7 +192,7 @@ DesktopDoubleBuffered = Y
</para>
<sect2>
<title>III.1 The Windowing system integration</title>
<title>The Windowing system integration</title>
<para>
This integration is done at two levels :
......@@ -222,7 +223,7 @@ DesktopDoubleBuffered = Y
</sect2>
<sect2>
<title>III.2 The thunks</title>
<title>The thunks</title>
<para>
The thunks are the Wine code that does the calling
......@@ -315,10 +316,10 @@ DesktopDoubleBuffered = Y
</sect1>
<sect1 id="opengl-problems">
<title>IV Known problems - shortcomings</title>
<title>Known problems - shortcomings</title>
<sect2>
<title>IV.1 Missing GLU32.DLL</title>
<title>Missing GLU32.DLL</title>
<para>
GLU is a library that is layered upon OpenGL. There is a
......@@ -338,7 +339,7 @@ DesktopDoubleBuffered = Y
</sect2>
<sect2>
<title>IV.2 OpenGL not detected at configure time</title>
<title>OpenGL not detected at configure time</title>
<para>
See section (I) for a detailed explanation of the
......@@ -347,7 +348,7 @@ DesktopDoubleBuffered = Y
</sect2>
<sect2>
<title>IV.3 When running an OpenGL application, the screen flickers</title>
<title>When running an OpenGL application, the screen flickers</title>
<para>
See section (II) for how to create the context
......@@ -356,11 +357,11 @@ DesktopDoubleBuffered = Y
</sect2>
<sect2>
<title>IV.4 Wine gives me the following error message : </title>
<title>Wine gives me the following error message : </title>
<screen>
Extension defined in the OpenGL library but NOT in opengl_ext.c...
Please report (lionel.ulmer@free.fr) !
Please report (&email-lionel-ulmer;) !
</screen>
<para>
......@@ -398,12 +399,12 @@ Please report (lionel.ulmer@free.fr) !
<para>
If you have this, run with <parameter>--debugmsg
+opengl</parameter> and send me
<email>lionel.ulmer@free.fr</email> the TRACE.
<email>&email-lionel-ulmer;</email> the TRACE.
</para>
</sect2>
<sect2>
<title>IV.5 <filename>libopengl32.so</filename> is built but it is still not working</title>
<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
......@@ -453,6 +454,6 @@ gcc dummy.c -L/usr/local/lib -lwine -lopengl32
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-parent-document:("wine-doc.sgml" "book" "part" "chapter" "")
sgml-parent-document:("wine-doc.sgml" "set" "book" "part" "chapter" "")
End:
-->
<chapter id="packaging">
<title>Packaging Wine</title>
<!-- Wine Packaging guidelines. This is a rough outline only,
and much of this was up for open debate on wine-devel. -->
<sect1 id="distributing">
<title>A Small WINE Distribution Guide</title>
<chapter id="pkg-preface"> <title>Preface</title>
<sect1 id="Authors"> <title>Authors</title>
<para>
Written by &name-marcus-meissner; <email>&email-marcus-meissner;</email>
Updated by &name-jeremy-white; <email>&email-jeremy-white;</email>
</para>
</sect1>
<sect1 id="Date"> <title>Document Revision Date</title>
<para>
The information contained in this document is extremely
time sensitive. <emphasis>It is vital that a packager
stay current with changes in Wine. </>
</para>
<para>
This document was last revised on November 2, 2000.</para>
</sect1>
<sect1 id="Terms"> <title>Terms used in this document</title>
<para>There are several terms and paths used in this
document as place holders for configurable values.
Those terms are described here.
</para>
<orderedlist>
<listitem id=WINECONFDIR><para id=wineconfdir.id><EnVar>WINECONFDIR</EnVar></para>
<para>
<envar>WINECONFDIR</envar> is the users Wine configuration directory.
This is almost always ~/.wine, but can be overridden
by the user by setting the <EnVar>WINECONFDIR</EnVar> environment
variable.
</para>
</listitem>
<listitem id=PREFIX><para id=prefix.id><EnVar>PREFIX</EnVar></para>
<para>
<envar>PREFIX</envar> is the prefix used when selecting
an installation target. The current default is /usr.
This results in binary installation into /usr/bin,
library installation into /usr/wine/lib, and so forth.
This value can be overridden by the packager.
In fact, <ulink url="http://www.pathname.com/fhs/">FHS 2.1</ulink>
specifications suggest that a better
prefix is /opt/wine. Ideally, a packager would also
allow the installer to override this value.
</para>
</listitem>
<listitem id=ETCDIR><para id=etcdir.id><EnVar>ETCDIR</EnVar></para>
<para>
<envar>ETCDIR</envar> is the prefix that Wine uses
to find the global configuration directory.
This can be changed by the configure option sysconfdir.
The current default is /etc.
</para>
</listitem>
<listitem id=WINDOWSDIR><para id=windowsdir.id><EnVar>WINDOWSDIR</EnVar></para>
<para>
<envar>WINDOWSDIR</envar> is an important concept
to Wine. This directory specifies what directory
corresponds to the root Windows directory
(e.g. C:\WINDOWS).
</para>
<para>
This directory is specified by the user, in
the users <link linkend=winerc>configuration file</link>.
</para>
<para>
Generally speaking, this directory is either set
to point at an empty directory, or it is set
to point at a Windows partition that has been
mounted through the vfat driver.
</para>
<para>
<emphasis>It is extremely important that the packager
understand the importance of <envar>WINDOWSDIR</envar>
and convey this information and choice to the end
user</emphasis>.
</para>
</listitem>
</orderedlist>
</sect1>
</chapter>
<chapter id="pkg-introduction"> <title>Introduction</title>
<para>
This document attempts to establish guidelines
for people making binary packages of Wine.
</para>
<para>
It expresses the basic principles that the
Wine developers have agreed should be
used when building Wine.
It also attempts to highlight the areas
where there are different approaches
to packaging Wine, so that the packager
can understand the different alternatives
that have been considered and their rationales.
</para>
<sect1 id="Goals"> <title>Goals</title>
<para>
An installation from a Wine pacakage should:
</para>
<itemizedlist>
<listitem>
<para>
Install quickly and simply.
</para>
<para>
The initial installation should require no user
input. An rpm -i wine.rpm or apt get wine
should suffice for initial installation.
</para>
</listitem>
<listitem>
<para>
Work quickly and simply
</para>
<para>
The user should be able to launch Solitaire
within minutes of downloading the Wine package.
</para>
</listitem>
<listitem>
<para>
Comply with Filesystem Hierarchy Standard
</para>
<para>
A Wine installation should, as much as possible, comply
with the
<ulink url="http://www.pathname.com/fhs/">FHS standard</ulink>.
</para>
</listitem>
<listitem>
<para>
Preserve flexibility
</para>
<para>
None of the flexibility built into Wine should
be hidden from the end user.
</para>
</listitem>
<listitem>
<para>
Come as preconfigured as possible, so the user does
not need to change any configuration files.
</para>
</listitem>
<listitem>
<para>Use only as much diskspace as needed per user.</para>
</listitem>
<listitem>
<para>
Reduce support requirements.
</para>
<para>
A packaged version of Wine should be sufficiently easy
to use and have quick and easy access to FAQs and
documentation such that requests to the
newsgroup and development group go down.
Further, it should be easy for users to capture
good bug reports.
</para>
</listitem>
</itemizedlist>
</sect1>
<sect1 id="Requirements"> <title>Requirements</title>
<para>
Successfully installing Wine requires:
</para>
<itemizedlist>
<listitem>
<para>Much thought and work from the packager (1x)</para>
</listitem>
<listitem>
<para>
A configuration file
</para>
<para>
Wine will not run with out a configuration file. Further,
no default is currently provided by Wine. Some packagers may attempt
to provide (or dynamically generate) a default configuration
file. Some packagers may wish to
rely on winecfg to generate the configuration file.
</para>
</listitem>
<listitem>
<para>
A writeable <filename>C:\</filename> directory
structure on a per user basis. Applications do dump
<filename>.ini</filename> files into
<filename>c:\windows</filename>, installers dump
<filename>.exe</filename>, <filename>.dll</filename>
and more into <filename>c:\windows\</filename> and
subdirectories or into <filename>C:\Program
Files\</filename>.
</para>
</listitem>
<listitem>
<para>
An initial set of registry entries.
</para>
<para>
The current Wine standard is to use the regapi tool
against the 'winedefault.reg' file to generate
a default registry.
</para>
<para>
There are several other choices that could be made;
registries can be imported from a Windows partition.
At this time, Wine does not completely support
a complex multi user installation, ala Windows NT,
but it could fairly readily.
</para>
</listitem>
<listitem>
<para>
Some special <filename>.dll</filename> and
<filename>.exe</filename> files in the
<filename>windows\system</filename> directory, since
applications directly check for their presence.
</para>
</listitem>
</itemizedlist>
</sect1>
</chapter>
<chapter id="Components"><title>Wine Components</title>
<para>
This section lists all files that pertain to Wine.
</para>
<sect1 id=static><title>Wine Static and Shareable Files</title>
<para>
At the time of this writing, the following components
are installed through a standard 'make install'
of Wine.
<caution>
<para>
It is vital that a packager check for
changes in Wine. This list will likely be out
of date by the time this document is committed to CVS.
</para>
</caution>
</para>
<orderedlist>
<listitem id=binfiles>
<variablelist><title>Executable Files</title>
<varlistentry><term><filename>wine</filename></term>
<listitem>
<para>
The main Wine executable. This program will load
a Windows binary and run it, relying upon
the Wine shared object libraries.
</para>
</listitem>
</varlistentry>
<varlistentry><term><filename>wineserver</filename></term>
<listitem>
<para>
The Wine server is critical to Wine; it is the
process that coordinates all shared Windows
resources.
</para>
</listitem>
</varlistentry>
<varlistentry><term><filename>wineclipsrv</filename></term>
<listitem>
<para>
The Wine Clipboard Server is a standalone XLib
application whose purpose is to manage the X selection
when Wine exits.
</para>
</listitem>
</varlistentry>
<varlistentry><term><filename>winedbg</filename></term>
<listitem>
<para>
Winedbg is the Wine built in debugger.
</para>
</listitem>
</varlistentry>
<varlistentry><term><filename>winecfg</filename></term>
<listitem>
<para>
This is a Tcl/Tk based front end that provides
a user friendly tool to edit and configure
the <link linkend=WINECONFDIR endterm=wineconfdir.id></link>/config file.
</para>
</listitem>
</varlistentry>
<varlistentry><term><filename>wineshelllink</filename></term>
<listitem>
<para>
This shell script can be called by Wine in order
to propogate Desktop icon and menu creation
requests out to a GNOME or KDE (or other
Window Managers).
</para>
</listitem>
</varlistentry>
<varlistentry><term><filename>winebuild</filename></term>
<listitem>
<para>
Winebuild is a tool used for Winelib applications
(and by Wine itself) to allow a developer to
compile a .spec file into a .spec.c file.
</para>
</listitem>
</varlistentry>
<varlistentry><term><filename>wmc</filename></term>
<listitem>
<para>
The wmc tools is the Wine Message Compiler. It
allows Windows message files to be compiled
into a format usable by Wine.
</para>
</listitem>
</varlistentry>
<varlistentry><term><filename>wrc</filename></term>
<listitem>
<para>
The wrc tool is the Wine Resource Compiler.
It allows Winelib programmers (and Wine itself)
to compile Windows style resource files
into a form usable by Wine.
</para>
</listitem>
</varlistentry>
<varlistentry><term><filename>fnt2bdf</filename></term>
<listitem>
<para>
The fnt2bdf utility extracts fonts from .fnt or
.dll files and stores then in .dbf format files.
</para>
</listitem>
</varlistentry>
<varlistentry><term><filename>dosmod</filename></term>
<listitem>
<para>
DOS Virtual Machine.
</para>
</listitem>
</varlistentry>
</variablelist>
</listitem>
<listitem id=libfiles>
<para> Shared Object Library Files </para>
<simplelist columns=5>
<member>libwine.so.1.0</>
<member>libddraw.so.1.0</>
<member>libopengl32.so.1.0</>
<member>libx11drv.so.1.0</>
<member>libadvapi32.so.1.0</>
<member>libavifil32.so.1.0</>
<member>libcomctl32.so.1.0</>
<member>libcomdlg32.so.1.0</>
<member>libcrtdll.so.1.0</>
<member>libdciman32.so.1.0</>
<member>libdinput.so.1.0</>
<member>libdplay.so.1.0</>
<member>libdplayx.so.1.0</>
<member>libdsound.so.1.0</>
<member>libgdi32.so.1.0</>
<member>libicmp.so.1.0</>
<member>libimagehlp.so.1.0</>
<member>libimm32.so.1.0</>
<member>libkernel32.so.1.0</>
<member>liblz32.so.1.0</>
<member>libmpr.so.1.0</>
<member>libmsacm32.so.1.0</>
<member>libmsnet32.so.1.0</>
<member>libmsvfw32.so.1.0</>
<member>libodbc32.so.1.0</>
<member>libole32.so.1.0</>
<member>liboleaut32.so.1.0</>
<member>libolecli32.so.1.0</>
<member>liboledlg.so.1.0</>
<member>libolepro32.so.1.0</>
<member>libolesvr32.so.1.0</>
<member>libpsapi.so.1.0</>
<member>librasapi32.so.1.0</>
<member>libriched32.so.1.0</>
<member>librpcrt4.so.1.0</>
<member>libserialui.so.1.0</>
<member>libsetupapi.so.1.0</>
<member>libshell32.so.1.0</>
<member>libshfolder.so.1.0</>
<member>libshlwapi.so.1.0</>
<member>libtapi32.so.1.0</>
<member>libttydrv.so.1.0</>
<member>liburlmon.so.1.0</>
<member>libuser32.so.1.0</>
<member>libversion.so.1.0</>
<member>libw32skrnl.so.1.0</>
<member>libwnaspi32.so.1.0</>
<member>libwineps.so.1.0</>
<member>libwininet.so.1.0</>
<member>libjoystick.drv.so.1.0</>
<member>libwinmm.so.1.0</>
<member>libmcianim.drv.so.1.0</>
<member>libmciavi.drv.so.1.0</>
<member>libmcicda.drv.so.1.0</>
<member>libmciseq.drv.so.1.0</>
<member>libmciwave.drv.so.1.0</>
<member>libmidimap.drv.so.1.0</>
<member>libmsacm.drv.so.1.0</>
<member>libwineoss.drv.so.1.0</>
<member>libws2_32.so.1.0</>
<member>libwinspool.drv.so.1.0</>
<member>libwow32.so.1.0</>
<member>libwsock32.so.1.0</>
<member>libwine_unicode.so.1.0</>
</simplelist>
</listitem>
<listitem id=manfiles>
<para> Man Pages</para>
<simplelist columns=1>
<member>wine.man</>
<member>wine.conf.man</>
<member>wmc.man</>
<member>wrc.man</>
</simplelist>
</listitem>
<listitem id=includefiles>
<para> Include Files</para>
<simplelist columns=5>
<member>basetsd.h</>
<member>cderr.h</>
<member>cguid.h</>
<member>commctrl.h</>
<member>commdlg.h</>
<member>compobj.h</>
<member>d3d.h</>
<member>d3dcaps.h</>
<member>d3dtypes.h</>
<member>d3dvec.inl</>
<member>dde.h</>
<member>ddeml.h</>
<member>ddraw.h</>
<member>digitalv.h</>
<member>dinput.h</>
<member>dispdib.h</>
<member>dlgs.h</>
<member>docobj.h</>
<member>dplay.h</>
<member>dplobby.h</>
<member>dsound.h</>
<member>guiddef.h</>
<member>imagehlp.h</>
<member>imm.h</>
<member>initguid.h</>
<member>instance.h</>
<member>lmcons.h</>
<member>lzexpand.h</>
<member>mapidefs.h</>
<member>mcx.h</>
<member>mmreg.h</>
<member>mmsystem.h</>
<member>msacm.h</>
<member>ntsecapi.h</>
<member>oaidl.h</>
<member>objbase.h</>
<member>objidl.h</>
<member>ocidl.h</>
<member>ole2.h</>
<member>ole2ver.h</>
<member>oleauto.h</>
<member>olectl.h</>
<member>oledlg.h</>
<member>oleidl.h</>
<member>poppack.h</>
<member>prsht.h</>
<member>psapi.h</>
<member>pshpack1.h</>
<member>pshpack2.h</>
<member>pshpack4.h</>
<member>pshpack8.h</>
<member>ras.h</>
<member>regstr.h</>
<member>richedit.h</>
<member>rpc.h</>
<member>servprov.h</>
<member>shellapi.h</>
<member>shlguid.h</>
<member>shlobj.h</>
<member>shlwapi.h</>
<member>sql.h</>
<member>sqlext.h</>
<member>sqltypes.h</>
<member>storage.h</>
<member>tapi.h</>
<member>tlhelp32.h</>
<member>unknwn.h</>
<member>urlmon.h</>
<member>ver.h</>
<member>vfw.h</>
<member>winbase.h</>
<member>wincon.h</>
<member>wincrypt.h</>
<member>windef.h</>
<member>windows.h</>
<member>windowsx.h</>
<member>wine/exception.h</>
<member>wine/icmpapi.h</>
<member>wine/ipexport.h</>
<member>wine/obj_base.h</>
<member>wine/obj_cache.h</>
<member>wine/obj_channel.h</>
<member>wine/obj_clientserver.h</>
<member>wine/obj_commdlgbrowser.h</>
<member>wine/obj_connection.h</>
<member>wine/obj_contextmenu.h</>
<member>wine/obj_control.h</>
<member>wine/obj_dataobject.h</>
<member>wine/obj_dockingwindowframe.h</>
<member>wine/obj_dragdrop.h</>
<member>wine/obj_enumidlist.h</>
<member>wine/obj_errorinfo.h</>
<member>wine/obj_extracticon.h</>
<member>wine/obj_inplace.h</>
<member>wine/obj_marshal.h</>
<member>wine/obj_misc.h</>
<member>wine/obj_moniker.h</>
<member>wine/obj_oleaut.h</>
<member>wine/obj_olefont.h</>
<member>wine/obj_oleobj.h</>
<member>wine/obj_oleundo.h</>
<member>wine/obj_oleview.h</>
<member>wine/obj_picture.h</>
<member>wine/obj_property.h</>
<member>wine/obj_propertystorage.h</>
<member>wine/obj_queryassociations.h</>
<member>wine/obj_shellbrowser.h</>
<member>wine/obj_shellextinit.h</>
<member>wine/obj_shellfolder.h</>
<member>wine/obj_shelllink.h</>
<member>wine/obj_shellview.h</>
<member>wine/obj_storage.h</>
<member>wine/unicode.h</>
<member>winerror.h</>
<member>wingdi.h</>
<member>wininet.h</>
<member>winioctl.h</>
<member>winnetwk.h</>
<member>winnls.h</>
<member>winnt.h</>
<member>winreg.h</>
<member>winresrc.h</>
<member>winsock.h</>
<member>winsock2.h</>
<member>winspool.h</>
<member>winsvc.h</>
<member>winuser.h</>
<member>winver.h</>
<member>wnaspi32.h</>
<member>wownt32.h</>
<member>wtypes.h</>
<member>zmouse.h</>
</simplelist>
</listitem>
<listitem id=docfiles>
<para>
Documentation files.
</para>
<para>
At the time of this writing, I do not have a
definitive list of documentation files to
be installed. However, they do include
the HTML files generated from the SGML in the Wine CVS tree.
</para>
</listitem>
</orderedlist>
</sect1>
<sect1 id=nonstatic><title>Dynamic Wine Files</title>
<para>
Wine also generates and depends on a number of dynamic
files, including user configuration files and registry files.
</para>
<para>
At the time of this writing, there was not a clear
consensus of where these files should be located, and how
they should be handled. This section attempts
to explain the alternatives clearly.
</para>
<orderedlist>
<listitem>
<variablelist><title>Configuration File</title>
<varlistentry id=winerc><term><filename><link linkend=WINECONFDIR endterm=wineconfdir.id></link>/config</filename></term>
<listitem>
<para>
This file is the user local Wine configuration file.
At the time of this writing, if this file exists,
then no other configuration file is loaded.
</para>
</listitem>
</varlistentry>
<varlistentry><term>
<filename><link linkend=ETCDIR endterm=etcdir.id></link>/wine.conf</filename></term>
<listitem>
<para>
This is the global Wine configuration file. It
is only used if the user running Wine has
no local configuration file.
</para>
<para>
Some packagers feel that this file should not
be supplied, and that only a wine.conf.default
should be given here.
</para>
<para>
Other packagers feel that this file should
be the predominant file used, and that
users should only shift to a local configuration
file if they need to. An argument has been
made that the local configuration file
should inherit the global configuration file.
At this time, Wine does not do this;
please refer to the WineHQ discussion
archives for the debate concerning this.
</para>
<para>
This debate is addressed more completely
below, in <link linkend=strategy endterm=strategy.id></link>.
</para>
</listitem>
</varlistentry>
</variablelist>
</listitem>
<listitem>
<para>Registry Files</para>
<para>
In order to replicate the Windows registry system,
Wine stores registry entries in a series of files.
For an excellent overview of this issue, read
this
<ulink url="http://www.winehq.com/News/2000-25.html#FTR">
Wine Weekly News feature.</ulink>
</para>
<para>
The bottom line is that, at Wine server startup,
Wine loads all registry entries into memory
to create an in memory image of the registry.
The order of files which Wine uses to load
registry entries is extremely important,
as it affects what registry entries are
actually present. The order is roughly that
.dat files from a Windows partion are loaded,
then global registry settings from <link linkend=ETCDIR endterm=etcdir.id></link>,
and then finally local registry settings are
loaded from <link linkend=WINECONFDIR endterm=wineconfdir.id></link>
. As each set are loaded,
they can override the prior entries. Thus,
the local registry files take precedence.
</para>
<para>
Then, at exit (or at periodic intervals),
Wine will write either all registry entries
(or, with the default setting) changed
registry entries to files in the
<link linkend=WINECONFDIR endterm=wineconfdir.id></link>.
</para>
<variablelist>
<varlistentry><term><filename><link linkend=WINECONFDIR endterm=wineconfdir.id></link>/system.reg</filename></term>
<listitem>
<para>
This file contains the users local copy of
the HKEY_LOCAL_MACHINE registry hive. In general
use, it will contain only changes made to the
default registry values.
</para>
</listitem>
</varlistentry>
<varlistentry><term><filename><link linkend=WINECONFDIR endterm=wineconfdir.id></link>/user.reg</filename></term>
<listitem>
<para>
written by Marcus Meissner &lt;Marcus.Meissner@caldera.de>
This file contains the users local copy of
the HKEY_CURRENT_USER registry hive. In
general use, it will contain only changes made to the
default registry values.
</para>
</listitem>
</varlistentry>
<varlistentry><term><filename><link linkend=WINECONFDIR endterm=wineconfdir.id></link>/userdef.reg</filename></term>
<listitem>
<para>
(Extracted from <filename>wine/documentation/distributors</filename>)
This file contains the users local copy of
the HKEY_USERS\.Default registry hive. In
general use, it will contain only changes made to the
default registry values.
</para>
</listitem>
</varlistentry>
<varlistentry><term><filename><link linkend=WINECONFDIR endterm=wineconfdir.id></link>/wine.userreg</filename></term>
<listitem>
<para>
While packaging WINE for one of the Linux distributions I came
across several points which have not been clarified yet.
Particularly a how-to for WINE packaging distributors is
missing. This document tries to give a brief overview over the
rationales I thought up and how I tried to implement it.
(While the examples use <command>rpm</command> most of this
stuff can be applied to other packagers too.)
This file is being deprecated. It is only read
if there is no user.reg or wine.userreg, and
it supplied the contents of HKEY_USERS.
</para>
</listitem>
</varlistentry>
<varlistentry><term><filename><link linkend=ETCDIR endterm=etcdir.id></link>/wine.systemreg</filename></term>
<listitem>
<para>
This file contains the global values for
HKEY_LOCAL_MACHINE. The values in this file
can be overriden by the users local settings.
</para>
<note>
<para>
YOU SHOULD RECHECK THIS FILE EVERY TWO MONTHS OR SO
(<command>diff -uN</command> comes to my mind here...).
We'll be adding stuff constantly here in order to improve
the Wine environment !
The location of this directory is hard coded within
wine, generally to /etc. This will hopefully be
fixed at some point in the future.
</para>
</note>
</listitem>
</varlistentry>
<orderedlist>
<varlistentry><term><filename><link linkend=ETCDIR endterm=etcdir.id></link>/wine.userreg</filename></term>
<listitem>
<para>
This file contains the global values for
HKEY_USERS. The values in this file
can be overriden by the users local settings.
This file is likely to be deprecated in
favor of a global wine.userdef.reg that will
only contain HKEY_USERS/.Default.
</para>
</listitem>
</varlistentry>
</variablelist>
</listitem>
<para>Rationales</para>
<listitem>
<variablelist><title>Other files in <link linkend=WINECONFDIR endterm=wineconfdir.id></link></title>
<varlistentry><term><filename><link linkend=WINECONFDIR endterm=wineconfdir.id></link>/wineserver-[username]</filename></term>
<listitem>
<para>
A WINE install should:
This directory contains files used by Wine and the Wineserver
to communicate. A packager may want to have a facility
for the user to erase files in this directory,
as a crash in the wineserver resulting in a bogus lock
file can render wine unusable.
</para>
<itemizedlist>
</listitem>
</varlistentry>
<varlistentry><term><filename><link linkend=WINECONFDIR endterm=wineconfdir.id></link>/cachedmetrics.[display]</filename></term>
<listitem>
<para>Not have a world writeable directory (-tree).</para>
<para>
This file contains font metrics for the given X display.
Generally, this cache is generated once at Wine start time.
</para>
</listitem>
</varlistentry>
</variablelist>
</listitem>
</orderedlist>
</sect1>
<sect1 id=winpartition><title>Important Files from a Windows Partition</title>
<para>
Wine has the ability to use files from an installation of the
actual Microsoft Windows operating system. Generally these
files are loaded on a VFAT partition that is mounted
under Linux.
</para>
<para>
This is probably the most important configuration detail.
The use of Windows registry and DLL files dramatically
alters the behaviour of Wine. If nothing else,
pacakager have to make this distinction clear
to the end user, so that they can intelligently
choose their configuration.
</para>
<orderedlist>
<listitem>
<variablelist><title>Registry Files</title>
<varlistentry><term><filename>[WINDOWSDIR]/system32/system.dat</filename></term>
<listitem>
<para>
Require only as much user input as needed. It would be
very good if it would not require any at all. Just let
the system administrator do <command>rpm -i
wine.rpm</command> and let any user be able to run
<command>wine sol.exe</command> instantly.
</para>
</listitem>
</varlistentry>
<varlistentry><term><filename>[WINDOWSDIR]/system32/user.dat</filename></term>
<listitem>
<para>
Give the user as much flexibility as possible to
install his own applications, do his own configuring
etc.
</para>
</listitem>
</varlistentry>
<varlistentry><term><filename>[WINDOWSDIR]/win.ini</filename></term>
<listitem>
<para>
Come as preconfigured as possible, so the user does
not need to change any configuration files.
</para>
</listitem>
</varlistentry>
</variablelist>
</listitem>
<listitem>
<para>Use only as much diskspace as needed per user.</para>
<para>
Windows Dynamic Link Libraries ([WINDOWSDIR]/system32/*.dll)
</para>
<para>
Wine has the ability to use the actuall Windows DLL files
when running an application. An end user can configure
Wine so that Wine uses some or all of these DLL files
when running a given application.
</para>
</listitem>
</itemizedlist>
</orderedlist>
</sect1>
</chapter>
<chapter id=strategy><title id=strategy.id>Packaging Strategies</title>
<para>
There has recently been a lot of discussion on the Wine
development mailing list about the best way to
build Wine packages.
</para>
<para>
There was a lot of discussion, and several diverging
points of view. This section of the document
attempts to present the areas of common agreement,
and also to present the different approaches
advocated on the mailing list.
</para>
<sect1 id=whatfiles><title>Distribution of Wine into packages</title>
<para>
A WINE install needs:
The most basic question to ask is given the Wine CVS tree,
what physical files are you, the packager, going to produce?
Are you going to produce only a wine.rpm (as Marcus has done),
or are you going to produce 5 debian files
(libwine-dev, libwine, wine-doc, wine-utils, and wine) as
Ove has done?
</para>
<para>
At this point, there is no consensus
amongst the wine-devel community on this subject.
</para>
</sect1>
<sect1 id=wherefiles><title>Where to install files</title>
<para>
This question is not really contested. It will vary
by distribution, and is really up to the packager.
As a guideline, the current 'make install' process
seems to behave such that
if we pick a single <link linkend=PREFIX endterm=prefix.id></link>,
then :
</para>
<orderedlist>
<itemizedlist>
<listitem>
<para>
A writeable <filename>C:\</filename> directory
structure on a per user basis. Applications do dump
<filename>.ini</filename> files into
<filename>c:\windows</filename>, installers dump
<filename>.exe</filename>, <filename>.dll</filename>
and more into <filename>c:\windows\</filename> and
subdirectories or into <filename>C:\Program
Files\</filename>.
all <link linkend=binfiles>binary files</link> go into
<link linkend=PREFIX endterm=prefix.id></link>/bin,
</para>
</listitem>
<listitem>
<para>
The <filename>.exe</filename> and
<filename>.dll</filename> from a global read-only
Windows installation to be found by applications.
all <link linkend=libfiles>library files</link> go into
<link linkend=PREFIX endterm=prefix.id></link>/lib,
</para>
</listitem>
<listitem>
<para>
Some special <filename>.dll</filename> and
<filename>.exe</filename> files in the
<filename>windows\system</filename> directory, since
applications directly check for their presence.
all <link linkend=includefiles>include files</link> go into
<link linkend=PREFIX endterm=prefix.id></link>/include,
</para>
</listitem>
<listitem>
<para>Some special program environment.</para>
<para>
all <link linkend=docfiles>documentation files</link> go into
<link linkend=PREFIX endterm=prefix.id></link>/doc/wine,
</para>
</listitem>
</itemizedlist>
<listitem>
<para>
and <link linkend=manfiles>man pages</link> go into
<link linkend=PREFIX endterm=prefix.id></link>/man,
</para>
</listitem>
</orderedlist>
<para>
Refer to the specific information on the Debian package
and the OpenLinux package for specific details on how
those packages are built.
</para>
<sect2 id=opt><title>The question of /opt/wine</title>
<para>
The FHS 2.1 specification suggests that Wine as a package
should be installed to /opt/wine. None of the
existing packages follow this guideline (today;
check again tomorrow).
</para>
</sect2>
</sect1>
<sect1 id=whattomake><title>What files to create</title>
<para>
After installing the static and shareable files, the next
question the packager needs to ask is how much dynamic
configuration will be done, and what configuration
files should be created.
</para>
<para>
There are several approaches to this:
<orderedlist>
<listitem>
<para>
Rely completely on user file space - install nothing
</para>
<para>
This approach relies upon the new winecfg utility and
the new ability of Wine to launch winecfg if no configuration file is found.
The basic concept is that no global configuration files
are created at install time.
Instead, Wine configuration files are created on the
fly by the winecfg program when Wine is invoked.
Further, winecfg creates default Windows directories
and paths that are stored completely in
the users <link linkend=WINECONFDIR endterm=wineconfdir.id></link>.
</para>
<para>
This approach has the benefit of simplicity in that all
Wine files are either stored under /opt/wine or under
~/.wine. Further, there is only ever one Wine
configuration file.
</para>
<para>
This approach, however, adds another level of complexity.
It does not allow Wine to run Solitaire 'out of the box';
the user must run the configuration program first. Further,
winecfg requires Tcl/Tk, a requirement not beloved by some.
Additionally, this approach closes the door on multi
user configurations and presumes a single user approach.
</para>
</listitem>
<listitem>
<para>
Build a reasonable set of defaults for the global wine.conf,
facilitate creation of a user's local Wine configuration.
</para>
<para>
This approach, best shown by Marcus, causes the
installation process to auto scan the system,
and generate a global wine.conf file with best
guess defaults. The OpenLinux packages follow
this behaviour.
</para>
<para>
The keys to this approach are always putting
an existing Windows partition into the
path, and being able to run Solitaire
right out of the box.
Another good thing that Marcus does is he
detects a first time installation and
does some clever things to improve the
user's Wine experience.
</para>
<para>
A flaw with this approach, however, is it doesn't
give the user an obvious way to choose not to
use a Windows partition.
</para>
</listitem>
<listitem>
<para>Implementation</para>
<para>
Build a reasonable set of defaults for the global wine.conf,
and ask the user if possible
</para>
<para>
This approach, demonstrated by Ove, causes the
installation process to auto scan the system,
and generate a global wine.conf file with best
guess defaults. Because Ove built a Debian
package, he was able to further query debconf and
get permission to ask the user some questions,
allowing the user to decide whether or not to
use a Windows partition.
</para>
</listitem>
</orderedlist>
</para>
</sect1>
<sect1 id=wineconf><title>What to put into the wine config file</title>
<para>
The next hard question is what the Wine config should look like.
The current best practices seems to involve using drives from M to Z.
</para>
<caution><para>This isn't done yet! Fix it, Jer!</para></caution>
</sect1>
</chapter>
<chapter id="pkg-Implementation"> <title>Implementation</title>
<sect1 id=OpenLinux><title>OpenLinux Sample</title>
<orderedlist inheritnum="inherit">
<listitem>
......@@ -157,8 +1180,8 @@ install -m 755 server/wineserver $BR/usr/X11R6/bin/
distributed <filename>winedefault.reg</filename>. This
can be done using <command>./regapi</command> once for
one example user and then reusing his
<filename>.wine/user.reg</filename> and
<filename>.wine/system.reg</filename> files.
<filename><link linkend=WINECONFDIR endterm=wineconfdir.id></link>/user.reg</filename> and
<filename><link linkend=WINECONFDIR endterm=wineconfdir.id></link>/system.reg</filename> files.
<note>
<title>FIXME</title>
<para>this needs to be done better</para>
......@@ -359,6 +1382,8 @@ Path=/
The user will need to run a setup script before the
first invocation of WINE. This script should:
</para>
<itemizedlist>
<listitem>
<para>
......@@ -415,43 +1440,17 @@ Path=/
</para>
</listitem>
</itemizedlist>
</listitem>
</orderedlist>
</listitem>
</orderedlist>
<para>Done.</para>
<para>
This procedure requires:
</para>
<itemizedlist>
<listitem>
<para>Much thought and work from the packager (1x)</para>
</listitem>
<listitem>
<para>
No work for the sysadmin. Well except one <command>rpm
-i</command> and possible one edit of the configuration
file.
</para>
</listitem>
<listitem>
<para>
Some or no work from the user, except running the per-user
setup script once.
</para>
</listitem>
<listitem>
<para>It scales well and suffices most of the rationales.</para>
</listitem>
</itemizedlist>
<sect2 id=sample><title>Sample <filename>wine.ini</filename> for OpenLinux 2.x:</title>
<programlisting>
<bridgehead>Sample <filename>wine.ini</filename> for OpenLinux 2.x:</bridgehead>
<programlisting>
;;
;; MS-DOS drives configuration
;;
......@@ -749,12 +1748,122 @@ Startup=
# &lt;/wineconf&gt;
</programlisting>
</sect2>
</sect1>
</chapter>
</chapter>
<chapter id=todo><Title>Work to be done</title>
<para>
In preparing this document, it became clear that there were
still a range of action items to be done in Wine
that would improve this packaging process.
For lack of a better place, I record them here.
<emphasis>This list is almost certain to be obsolete;
check bugzilla for a better list.</emphasis>
</para>
<orderedlist>
<listitem>
<para>
Remove duplication of code between winecfg and
wineconf/wineinstall.
</para>
<para>
Currently, winecfg duplicates all of the code contained
in wineconf.
</para>
<para>
Instead, wineconf should be improved to generate
the new style config file, and then winecfg should
rely on wineconf to generate the default
configuration file.
</para>
<para>
Similarly, there is functionality such as creating
the default registry files that is now done by
both winecfg and wineinstall.
</para>
<para>
At this time, it seems like the right thing to do
is to break up or parameterize wineinstall, so that
it can be used for single function actions,
and then have winecfg call those functions.
</para>
</listitem>
<listitem>
<para>
Enhance winecfg to support W: drive generation.
</para>
<para>
The best practices convention now seems to be
to generate a set of drives from M: through W:.
At this point, winecfg does not generate
a default wine config file that follows
these conventions. It should.
</para>
</listitem>
<listitem>
<para>
Enhance Wine to allow more dynamic switching
between the use of a real Windows partition
and an empty one.
</para>
</listitem>
<listitem>
<para>
Write a winelauncher utility application.
</para>
<para>
Currently, Wine really requires a user to launch it
from a command line, so that the user can look for
error messages and warnings. However, eventually, we will
want users to be able to launch Wine from a more
friendly GUI launcher. The launcher should have the
ability to allow the end user to turn on debugging
messages and capture those traces for bug reporting
purposes. Also, if we make it possible to
switch between use of a Windows partition or not
automatically, that option should be controlled here.
</para>
</listitem>
<listitem>
<para>
Get Marcus's winesetup facilities into CVS
</para>
<para>
Along the lines of the changes to winecfg,
and the consolidation of wineconf and wineinstall,
we should extract the good stuff from Marcus's
winesetup script, and get it into CVS.
Again, perhaps we should have a set of scripts
that perform discrete functions, or maybe
one script with parameters.
</para>
</listitem>
<listitem>
<para>
Finish this document
</para>
<para>
This document is pretty rough itself. Many hard
things aren't addressed, and lots of stuff was missed.
</para>
</listitem>
</orderedlist>
</chapter>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-parent-document:("wine-doc.sgml" "book" "part" "chapter" "")
sgml-parent-document:("wine-doc.sgml" "set" "book" "chapter" "")
End:
-->
<chapter id="patches">
<title>Submitting Patches</title>
<para>How to create patches, and where to send them...</para>
<para>
Written by &name-albert-den-haan; <email>&email-albert-den-haan;</email>
</para>
<sect1 id="patch-format">
<title>Patch Format</title>
<para>
Your patch should include:
</para>
<itemizedlist>
<listitem>
<para>
a description of what was wrong and what is now better
(and now broken :).
</para>
</listitem>
<listitem>
<para>
your contact information ( Name/Handle and e-mail )
</para>
</listitem>
<listitem>
<para>
the patch in <command>diff -u</command> format (it happens...)
</para>
</listitem>
</itemizedlist>
<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: mention that you have some new files and
include them as either separate attachments or by appending
<command>diff -Nu</command> of them to any <command>cvs diff
-u</command> output you may have.
</para>
<para>
For removals, list the files.
</para>
</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 commited 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 embarasment and run your patched code
against more than just your current test example. Experience
will tell you how much effort to apply here.
</para>
</sect1>
</chapter>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-parent-document:("wine-doc.sgml" "book" "part" "chapter" "")
sgml-parent-document:("wine-doc.sgml" "set" "book" "part" "chapter" "")
End:
-->
......@@ -236,8 +236,8 @@ AC_CHECK_HEADER(foo.h, AC_DEFINE(HAVE_FOO_H))
<title>Running & Compiling WINE in OS/2</title>
<para>
written by Robert Pouliot &lt;krynos@clic.net&gt;, January 9, 1997
Written by &name-robert-pouliot; <email>&email-robert-pouliot;</email>,
January 9, 1997
</para>
<para>
(Extracted from <filename>wine/documentation/wine_os2</filename>)
......@@ -390,6 +390,6 @@ AC_CHECK_HEADER(foo.h, AC_DEFINE(HAVE_FOO_H))
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-parent-document:("wine-doc.sgml" "book" "part" "chapter" "")
sgml-parent-document:("wine-doc.sgml" "set" "book" "part" "chapter" "")
End:
-->
......@@ -6,15 +6,14 @@
<title>Printing</title>
<para>
written by (???)
Written by &name-huw-davies; <email>&email-huw-davies;</email>
</para>
<para>
(Extracted from <filename>wine/documentation/printing</filename>)
</para>
<para>
Printing in Wine can be done in one of two ways. Both of which are very
alpha.
Printing in Wine can be done in one of two ways. Both of which are pretty alpha.
</para>
<orderedlist>
<listitem>
......@@ -30,8 +29,8 @@
<para>
Note that at the moment WinPrinters (cheap, dumb printers that require
the host computer to explicitly control the head) will not work. It is
unclear whether they ever will.
the host computer to explicitly control the head) will not work with
their Windows printer drivers. It is unclear whether they ever will.
</para>
<sect2>
......@@ -93,7 +92,7 @@ LPT1:=foo.ps LPT2:=|lpr
<title>The Wine PostScript Driver</title>
<para>
written by Huw Davies <email>h.davies1@physics.ox.ac.uk</email>
Written by &name-huw-davies; <email>&email-huw-davies;</email>
</para>
<para>
(Extracted from <filename>wine/documentation/psdriver</filename>)
......@@ -251,7 +250,7 @@ ppdfile=/somewhere/file.ppd
Please contact me if you want to help so that we can avoid duplication.
</para>
<para>
Huw Davies <email>h.davies1@physics.ox.ac.uk</email>
&name-huw-davies; <email>&email-huw-davies;</email>
</para>
</sect2>
</sect1>
......@@ -260,6 +259,6 @@ ppdfile=/somewhere/file.ppd
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-parent-document:("wine-doc.sgml" "book" "chapter" "")
sgml-parent-document:("wine-doc.sgml" "set" "book" "chapter" "")
End:
-->
......@@ -102,7 +102,7 @@
</sect2>
<sect2>
<title>Wine registry data filesr</title>
<title>Wine registry data files</title>
<para>
In the user's home directory, there is a subdirectory named
......
<chapter id="running">
<title>Running Wine</title>
<para>Explain the command-line options you can use to run Wine</para>
<para>
Written by &name-john-sheets; <email>&email-john-sheets;</email>
</para>
<sect1 id="running-wine">
<title>How to run Wine</title>
<para>
The first thing you need to do is...
Wine is a very complicated piece of software with many ways to
adjust how it runs. With very few exceptions, you can
activate the same set of features through the <link
linkend="configuring">configuration file </link> as you can
with command-line parameters. In this chapter, we'll briefly
discuss these parameters, and match them up with their
corresponding configuration variables.
</para>
<para>
You can invoke the <command>wine --help</command> command to
get a listing of all Wine's command-line parameters:
</para>
<para>
<screen>
Usage: ./wine [options] program_name [arguments]
Options:
--config name Specify config file to use
--debugmsg name Turn debugging-messages on or off
--desktop geom Use a desktop window of the given geometry
--display name Use the specified display
--dll name Enable or disable built-in DLLs
--dosver x.xx DOS version to imitate (e.g. 6.22)
Only valid with --winver win31
--help,-h Show this help message
--language xx Set the language (one of Br,Ca,Cs,Cy,Da,De,En,Eo,Es,Fi,Fr,Ga,Gd,Gv,
Hr,Hu,It,Ja,Ko,Kw,Nl,No,Pl,Pt,Sk,Sv,Ru,Wa)
--managed Allow the window manager to manage created windows
--synchronous Turn on synchronous display mode
--version,-v Display the Wine version
--winver Version to imitate (win95,nt40,win31,nt2k,win98,nt351,win30,win20)
</screen>
</para>
<para>
You can specify as many options as you want, if any.
Typically, you will want to have your configuration file set
up with a sensible set of defaults; in this case, you can run
<command>wine</command> without explicitly listing any
options. In rare cases, you might want to override certain
parameters on the command line. If you find yourself using
the same long set of command options with certain
applications, you might find it easier to work with multiple
config files, using the <link
linkend="config-parameter"><parameter>--config</parameter>
parameter</link> to specify a non-default configuration.
</para>
<para>
After the options, you should put the name of the file you
want <command>wine</command> to execute. If the executable is
in the <parameter>Path</parameter> parameter in the
configuration file, 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>
[wine]
"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>
Finally, if you want to pass any parameters to your windows
application, you can list them at the end, just after the
executable name. Thus, to run the imaginary
<command>foo.exe</command> Windows application with its
<parameter>/advanced</parameter> mode parameter, while
invoking Wine in <link
linkend="managed-parameter"><parameter>--managed</parameter>
mode</link>, you would do something like this:
</para>
<screen>
<prompt>$</prompt> <userinput>wine --managed foo.exe /advanced</userinput>
</screen>
<para>
In other words, options that affect Wine should come
<emphasis>before</emphasis> the Windows program name, while
options that affect the Windows program should come
<emphasis>after</emphasis> it.
</para>
</sect1>
<sect1 id="command-line-options">
<title>Command-Line Options</title>
<sect2 id="config-parameter">
<title>--config</title>
<para>
The <parameter>--config</parameter> parameter allows you to
specify which configuration file you want to use for the
current invocation of <command>wine</command>. For example,
if you like to run a specific application or set of
applications with a different array of options than your
normal defaults, you might set up a different config file
for them, and use the <parameter>--config</parameter> option
to make use of it.
</para>
<para>
The default value of <parameter>--config</parameter> is
<filename>~/.winerc</filename>. This value is hardwired
into the Wine source code. In future versions of Wine, the
default may change to <filename>~/.wine/conf</filename>.
</para>
</sect2>
<sect2>
<title>--debugmsg [channels]</title>
<para>
Wine isn't perfect, and many Windows applications still
don't run without bugs under Wine (but then, many of them
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. Logging does slow down Wine
quite a bit, so don't use <parameter>--debugmsg</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>--debugmsg</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>wine --debugmsg warn+heap <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>wine --debugmsg +heap <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>wine --debugmsg +all,-relay <replaceable>program_name</replaceable></userinput>
</screen>
<para>
Here is a master list of all the debug channels and classes
in Wine. More channels might be added to (or subtracted
from) later versions.
</para>
<screen>
all accel advapi animate aspi atom avifile bitblt
bitmap caret cdrom class clipboard clipping combo comboex
comm commctrl commdlg console crtdll cursor datetime dc
ddeml ddraw debug debugstr delayhlp dialog dinput dll
dosfs dosmem dplay driver dsound edit elfdll enhmetafile
event exec file fixup font gdi global graphics
header heap hook hotkey icmp icon imagehlp imagelist
imm int int10 int16 int17 int19 int21 int31
io ipaddress joystick key keyboard ldt listbox listview
local mci mcianim mciavi mcicda mcimidi mciwave mdi
menu message metafile midi mmaux mmio mmsys mmtime
module monthcal mpr msacm msg msvideo nativefont nonclient
ntdll odbc ole opengl pager palette pidl print
process profile progress prop propsheet psapi psdrv ras
rebar reg region relay resource richedit scroll segment
seh selector sendmsg server setupapi setupx shell snoop
sound static statusbar storage stress string syscolor system
tab tape tapi task text thread thunk timer
toolbar toolhelp tooltips trackbar treeview ttydrv tweak typelib
updown ver virtual vxd wave win win16drv win32
wing wininet winsock winspool wnet x11 x11drv
</screen>
<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>
<sect2>
<title>--desktop [geometry]</title>
<para>
By default, <command>wine</command> runs applications on
your regular desktop. Wine application windows intermingle
with native X11 applications. Windows overlap each other,
and you can resize them in relation to each other.
Normally, when you minimize Wine windows, they collapse into
a small icon at the lower left corner of your desktop,
circumventing the behavior of your other non-Wine windows.
However, if you're running in <link linkend="managed-parameter">
--managed mode</link>, your Wine applications will minimize
just like your other windows.
</para>
<para>
Sometimes, you may want to restrict Wine windows to a
smaller area of your desktop. This is what the
<parameter>--desktop</parameter> option controls. Whenever
you pass this option to <command>wine</command>, it will
create a window of that size and use that as Wine's desktop
instead of borrowing the regular desktop space. Wine will
then place the application window inside the new desktop
window. If you minimize the application, it will iconize to
the bottom left corner of its own desktop window.
</para>
<para>
The <parameter>--desktop</parameter> option geometry info in
the standard X11 geometry format, e.g., "640x480" for a
desktop window 640 pixels wide and 480 pixels high. You can
also in theory specify the coordinates of the upper left
corner of the desktop window, but your window manager may
choose to override that request. The following invocation
would open a new 640 x 480 desktop window at coordinates
(10, 25):
<screen>
<prompt>$</prompt> <userinput>wine --desktop 640x480+10+25 foo.exe</userinput>
</screen>
</para>
<para>
More commonly, you'll leave off the starting coordinates,
and only use the height and width:
<screen>
<prompt>$</prompt> <userinput>wine --desktop 640x480 foo.exe</userinput>
</screen>
</para>
</sect2>
<sect2>
<title>--display</title>
<para>
By default, wine will display its windows on whichever X
Display you have in the <envar>$DISPLAY</envar> environment
variable. Often, <envar>$DISPLAY</envar> is set to
<literal>:0</literal>, which sends all windows to the
primary video monitor on the current host machine.
</para>
<para>
To send windows to a different monitor on the same system,
you could change <literal>:0</literal> to a different
number, for example <literal>:1</literal> to send output to
the second monitor. You can also specify other systems. If
you were logged into the system <systemitem
class="systemname">alpha</systemitem>, but wanted wine to
run on another system on the network, <systemitem
class="systemname">beta</systemitem>, you might use a
<envar>$DISPLAY</envar> of <literal>beta:0</literal>.
</para>
<para>
You can also declare display values on the wine command
line, using the <parameter>--display</parameter> option.
The last example above might look like this:
</para>
<programlisting>
<prompt>$</prompt> wine --display="beta:0" foo.exe
</programlisting>
</sect2>
<sect2>
<title>--dll</title>
<para>
</para>
</sect2>
<sect2>
<title>--dosver</title>
<para>
</para>
</sect2>
<sect2>
<title>--help</title>
<para>
</para>
</sect2>
<sect2>
<title>--language</title>
<para>
</para>
</sect2>
<sect2 id="managed-parameter">
<title>--managed</title>
<para>
</para>
</sect2>
<sect2>
<title>--synchronous</title>
<para>
</para>
</sect2>
<sect2>
<title>--version</title>
<para>
</para>
</sect2>
<sect2>
<title>--winver</title>
<para>
</para>
</sect2>
</sect1>
</chapter>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-parent-document:("wine-doc.sgml" "book" "chapter" "")
sgml-parent-document:("wine-doc.sgml" "set" "book" "chapter" "")
End:
-->
......@@ -5,7 +5,7 @@
<title>bin2res</title>
<para>
written by juergen.schmied@debitel.net (11/99)
Written by &name-juergen-schmied; <email>&email-juergen-schmied;</email> (11/99)
</para>
<para>
(Extracted from <filename>wine/documentation/resources</filename>)
......@@ -89,6 +89,6 @@ bash-2.03# ../../tools/bin2res -d bin shres.rc
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-parent-document:("wine-doc.sgml" "book" "part" "chapter" "")
sgml-parent-document:("wine-doc.sgml" "set" "book" "part" "chapter" "")
End:
-->
<!doctype book PUBLIC "-//OASIS//DTD DocBook V3.1//EN" [
<!doctype set PUBLIC "-//OASIS//DTD DocBook V3.1//EN" [
<!entity running SYSTEM "running.sgml">
<!-- *** Include list of authors *** -->
<!entity % authors SYSTEM "authors.ent">
%authors;
<!-- *** Entities for Wine User Guide *** -->
<!entity introduction SYSTEM "introduction.sgml">
<!entity getting SYSTEM "getting.sgml">
<!entity installing SYSTEM "installing.sgml">
<!entity configuring SYSTEM "configuring.sgml">
<!entity registry SYSTEM "registry.sgml">
<!entity running SYSTEM "running.sgml">
<!entity bugs SYSTEM "bugs.sgml">
<!-- *** Not currently used (???) *** -->
<!entity fonts SYSTEM "fonts.sgml">
<!entity printing SYSTEM "printing.sgml">
<!-- *** Entities for Wine Developer Guide *** -->
<!entity compiling SYSTEM "compiling.sgml">
<!entity debugging SYSTEM "debugging.sgml">
<!entity documentation SYSTEM "documentation.sgml">
<!entity patches SYSTEM "patches.sgml">
<!entity i18n SYSTEM "i18n.sgml">
<!entity porting SYSTEM "porting.sgml">
<!entity packaging SYSTEM "packaging.sgml">
<!entity architecture SYSTEM "architecture.sgml">
<!entity ole SYSTEM "ole.sgml">
<!entity debugger SYSTEM "debugger.sgml">
<!entity consoles SYSTEM "consoles.sgml">
<!entity implementation SYSTEM "implementation.sgml">
......@@ -25,70 +33,95 @@
<!entity build SYSTEM "build.sgml">
<!entity tools SYSTEM "tools.sgml">
<!entity dlls SYSTEM "dlls.sgml">
<!entity status SYSTEM "status.sgml">
<!entity cvs-regression SYSTEM "cvs-regression.sgml">
<!-- *** Entities for Wine Developer Guide *** -->
<!entity winelib-user SYSTEM "winelib-user.sgml">
<!-- *** Entities for Wine Packager Guide *** -->
<!entity packaging SYSTEM "packaging.sgml">
]>
<book id="index">
<bookinfo>
<set id="index">
<setinfo>
<title>Wine Documentation</title>
</bookinfo>
<preface id="preface">
<title>Notes About this Document</title>
<para>
<releaseinfo>
<emphasis>
The following documentation has been extracted from the Wine
source tree, from the <filename>wine/documentation</filename>
directory. So far, no new content has been added aside from
marking it up for DocBook and a few minor tweaks to smooth
that process. All credit should go to the original authors,
who are attributed according the the "written by" comments
in those files. If I've missed anyone, please contact
<email>John R. Sheets &lt;jsheets@codeweavers.com></email>
</para>
</preface>
directory. All credit should go to the original authors, who
are attributed according the the "written by" comments in
those files. Additional content has also been added.
</emphasis>
</releaseinfo>
</setinfo>
<!-- *** Wine User Guide *** -->
<book id="index-user">
<bookinfo>
<title>Wine User Guide</title>
</bookinfo>
<part id="part-one">
<title>Using Wine</title>
&introduction;
&getting;
&running;
&installing;
&configuring;
&running;
&bugs;
<!--
&fonts;
&printing;
-->
</book>
</part>
<!-- *** Wine Developer Guide *** -->
<book id="index-developer">
<bookinfo>
<title>Wine Developer's Guide</title>
</bookinfo>
<part id="part-two">
<part id="part-one">
<title>Developing Wine</title>
&compiling;
&debugging;
&debugger;
&documentation;
&patches;
&i18n;
&porting;
</part>
<part id="part-three">
<title>Distributing Wine</title>
&packaging;
&tools;
</part>
<part id="part-four">
<part id="part-two">
<title>Wine Architecture</title>
&architecture;
&debugger;
&consoles;
&implementation;
&debugging;
&ole;
&opengl;
&build;
&tools;
&dlls;
</part>
<part>
<title>Advanced Topics</title>
&implementation;
&porting;
&consoles;
&cvs-regression;
</part>
</book>
</book>
<!-- *** Winelib User Guide *** -->
&winelib-user;
<!-- *** Wine Packager Guide *** -->
<book id="index-pkg">
<bookinfo>
<title>Wine Packagers Guide</title>
</bookinfo>
&packaging;
</book>
</set>
<!DOCTYPE style-sheet PUBLIC "-//James Clark//DTD DSSSL Style Sheet//EN" [
<!ENTITY walsh-style PUBLIC "-//Norman Walsh//DOCUMENT DocBook HTML Stylesheet//EN" CDATA DSSSL>
<!ENTITY cygnus-style SYSTEM "/usr/lib/sgml/stylesheet/dsssl/docbook/cygnus/cygnus-both.dsl" CDATA DSSSL>
]>
<style-sheet>
<style-specification id="html" use="docbook">
<style-specification-body>
(define %use-id-as-filename% #t)
(define %html-ext% ".shtml")
(define %html-header-tags% '())
(define %stylesheet% "../../winehq.css")
(define %stylesheet-type% "text/css")
(define %shade-verbatim% #t)
(define %section-autolabel% #t)
;; Define new HTML headers
(define ($html-body-start$)
(make sequence
(make formatting-instruction data: "&#60!--")
(literal "#include file=\"header.html\" ")
(make formatting-instruction data: "-->")))
(define ($html-body-end$)
(make sequence
(make formatting-instruction data: "&#60!--")
(literal "#include file=\"footer.html\" ")
(make formatting-instruction data: "-->")))
;; Customize the body tag attributes
(define %body-attr%
(list
(list "BGCOLOR" "#555555")
(list "TEXT" "#000000")
(list "LINK" "#0000FF")
(list "VLINK" "#840084")
(list "ALINK" "#0000FF")))
</style-specification-body>
</style-specification>
<external-specification id="docbook" document="walsh-style">
</style-sheet>
<book id="index-winelib">
<bookinfo>
<title>Winelib User Guide</title>
</bookinfo>
<chapter id="winelib-introduction">
<title id="introduction.title">Introduction</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 runnning 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>
</chapter>
<chapter 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 an uncharted territory. It would be more reasonable to
first 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>
</chapter>
<chapter id="winelib-getting-started">
<title id="getting-started.title">Getting Started</title>
<sect1 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 'Windows.h' instead of 'windows.h'.
</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 autoconf-based Makefiles.
</para>
<para>
Let's suppose that Wine/Winelib has been installed in the
<filename class="Directory">/usr/local/wine</filename>
directory, and 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:
</para>
<programlisting>
$ winemaker --lower-uppercase
$ ./configure --with-wine=/usr/local/wine
$ make
</programlisting>
<para>
But of course things are not always that simple which is why we have
this guide at all.
</para>
</sect1>
<sect1 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>
</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.
</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 the configure script</option></term>
<listitem>
<para>
Before you run <command>make</command> you must run the
autoconf <command>configure</command> script. The goal of this
step is to analyze your system and generate customized
makefiles from the <filename>Makefile.in</filename> files. This
is also when you have to tell where Winelib resides on your
system. If wine is installed in a single directory or you have
the Wine sources compiled somewhere then you can just run
<command>./configure --with-wine=/usr/local/bin</command>
or <command>./configure --with-wine=~/wine</command>
respectively.
</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.in</filename> files to
adjust the default compilation and link options set by
winemaker. 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>
</sect1>
</chapter>
<chapter id="portability-issues">
<title id="portability-issues.title">Portability issues</title>
<sect1 id="anon">
<title id="anon.title">Anonymous unions/structs</title>
<para>
Anonymous structs and unions support depends heavily on the compiler.
The best support is provided by gcc/g++ 2.96 and later. But these
versions of gcc come from the development branch so you may want to
hold off before using them in production. g++ 2.95 supports anonymous
unions but not anonymous structs and gcc 2.95 supports neither. Older
versions of gcc/g++ have no support for either.
since it is anonymous unions that are the most frequent in the
windows headers, you should at least try to use gcc/g++ 2.95.
</para>
<para>
But you are stuck with a compiler that does not support anonymous
structs/unions all is not lost. The Wine headers should detect this
automatically and define <varname>NONAMELESSUNION</varname> /
<varname>NONAMELESSSTRUCT</varname>. Then any anonymous union will
be given a name
<literal>u</literal> or <literal>u2</literal>, <literal>u3</literal>,
etc. to avoid name clashes. You will then have to modify your code to
include those names where appropriate.
</para>
<para>
The name that Wine adds to anonymous unions should match that used
by the Windows headers. So all you have to do to compile your
modified code in Windows is to explicitly define the
<varname>NONAMELESSUNION</varname> macro. Note that it would be wise
to also explicitly define this macro on in your Unix makefile
(<filename>Makefile.in</filename>) to make sure your code will
compile even if the compiler does support anonymous unions.
</para>
<para>
Things are not as nice when dealing with anonymous structs.
Unfortunately the Windows headers make no provisions for compilers
that do not support anonymous structs. So you will need to be more
subtle when modifying your code if you still want it to compile in
Windows. Here's a way to do it:
</para>
<programlisting>
#ifdef WINELIB
#define ANONS .s
#else
#define ANONS
#endif
. . .
{
SYSTEM_INFO si;
GetSystemInfo(&amp;si);
printf("Processor architecture=%d\n",si ANONS .wProcessorArchitecture);
}
</programlisting>
<para>
You may put the <literal>#define</literal> directive directly in the
source if only few files are impacted. Otherwise it's probably best
to put it in one of your project's widely used headers.
Fortunately usage of an anonymous struct is much rarer than usage of
an anonymous union so these modifications should not be too much work.
</para>
</sect1>
<sect1 id="unicode">
<title id="unicode.title">Unicode</title>
<para>
L"foo" generates 4-byte chars,
use __TEXT (or _TEXT?),
C library
</para>
</sect1>
<sect1 id="C-library">
<title id="C-library.title">C library</title>
<para>
Winelib currently only supports on C library: that of your compiler.
</para>
<para>
three solutions: native, mixed or msvcrt except we only have native right now,
using the native C library -> different behavior: fopen, O_TEXT,
unicode support,
reimplement msvcrt
</para>
</sect1>
<sect1 id="init-problems">
<title id="init-problems.title">Initialization problems</title>
<para>
Initialization problems occur when the application calls the Win32 API
before Winelib has been initialized. How can this happen?
</para>
<para>
Winelib is initialized by the application's <function>main</function>
before it calls the regular <function>WinMain</function>. But, in C++,
the constructors of static class variables are called before the
<function>main</function> (by the module's initializer). So if such
a constructor makes calls to the Win32 API, Winelib will not be
initialized at the time of the call and you may get a crash. This
problem is much more frequent in C++ because of these class
constructors but could also, at least in theory, happen in C if you
were to specify an initializer making calls to Winelib. But of
course, now that you are aware of this problem you won't do it :-).
</para>
<para>
Further compounding the problem is the fact that Linux's (GNU's?)
current dynamic library loader does not call the module
initializers in their dependency order. So even if Winelib were to
have its own initializer there would be no garantee that it would be
called before the initializer of the library containing this static
variable. Finally even if the variable is in a library that your
application links with, that library's initializer may be called
before Winelib has been initialized. One such library is the MFC.
</para>
<para>
The current workaround is to move all the application's code in a
library and to use a small Winelib application to dynamically load
this library. Tus the initialization sequence becomes:
</para>
<itemizedlist>
<listitem>
<para>
the wrapper application starts.
</para>
</listitem>
<listitem>
<para>
its empty initializer is run.
</para>
</listitem>
<listitem>
<para>
its <function>main</function> is run. Its first task is to
initialize Winelib.
</para>
</listitem>
<listitem>
<para>
it then loads the application's main library, plus all its
dependent libraries.
</para>
</listitem>
<listitem>
<para>
which triggers the execution of all these libraries initializers
in some unknown order. But all is fine because Winelib has
already been initialized anyway.
</para>
</listitem>
<listitem>
<para>
finally the main function calls the <function>WinMain</function>
of the application's library.
</para>
</listitem>
</itemizedlist>
<para>
This may sound complex by Winemaker makes it simple. Just specify
<option>--wrap</option> or <option>--mfc</option> on the command line
and it will adapt its makefiles to build the wrapper and the
application library.
</para>
</sect1>
<sect1 id="com-support">
<title id="com-support.title">VC's native COM support</title>
<para>
don't use it,
guide on how to replace it with normal C++ code (yes, how???):
extracting a .h and .lib from a COM dll
Can '-fno-rtti' be of some use or even required?
</para>
</sect1>
<sect1 id="SEH">
<title id="SEH.title">SEH</title>
<para>
how to modify the syntax so that it works both with gcc's macros and Wine's macros,
is it even possible?
</para>
</sect1>
<sect1 id="others">
<title id="others.title">Others</title>
<para>
-fpermissive and -fno-for-scope,
maybe other options
</para>
</sect1>
</chapter>
<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.in</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.in</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 overriden by using
<option>--nolower-include</option>).
</para>
<para>
Finally winemaker generates the <filename>Makefile.in</filename>
files and other support files (wrapper files, spec files,
<filename>configure.in</filename>,
<filename>Make.rules.in</filename>). From the above description
you can guess at the items that winemaker may get wrong in
this phase: macro definitions, include path, library path,
list of libraries to import. You can deal with these issues by
using winemaker's <option>-D</option>, <option>-I</option>,
<option>-L</option> and <option>-i</option> 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.in</filename> file(s).
</para>
<para>
Finally the most likely reasons for missing or duplicate symbols
are:
</para>
<itemizedlist>
<listitem>
<para>
The target is not being linked with the right set of libraries.
You can avoid this by using winemaker's <option>-L</option> and
<option>-i</option> options or adding these libraries to the
<filename>Makefile.in</filename> 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.in</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.in</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.in">
<title id="Makefile.in.title">The Makefile.in files</title>
<para>
The <filename>Makefile.in</filename> is your makefile. More
precisely it is the template from which the actual makefile will
be generated by the <filename>configure</filename> script. It also
relies on the <filename>Make.rules</filename> file for most of
the actual logic. This way it only contains a relatively simple
description of what needs to be built, not the complex logic of
how things are actually built.
</para>
<para>
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.in</filename> files yet).
</para>
<programlisting>
SUBDIRS =
DLLS =
EXES = hello
</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 you should
put the full Unix name, e.g. <literal>libfoo.so</literal>.
</para>
<programlisting>
### Global settings
DEFINES = -DSTRICT
INCLUDE_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</varname>
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 'import' statement of the
<link linkend="spec-file">spec files</link>. The exception is when you
have not explicitly exported the functions of a Winelib library. One
library you are likely to find here is <literal>mfc</literal> (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 except <varname>IMPORTS</varname>. So you should
put <literal>-DSTRICT</literal> in <varname>DEFINES</varname> but
<literal>winmm</literal> in <varname>IMPORTS</varname>.
</para>
<para>
Then come one section per target, each describing the various
components that target is made of.
</para>
<programlisting>
### hello sources and settings
hello_C_SRCS = hello.c
hello_CXX_SRCS =
hello_RC_SRCS =
hello_SPEC_SRCS = hello.spec
</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 always contain a single spec file.
</para>
<programlisting>
hello_LIBRARY_PATH =
hello_LIBRARIES =
hello_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>
<varname>DEPENDS</varname>, when present, specifies a list of other
targets that this target depends on. Winemaker will automatically
fill this field, and the <varname>LIBRARIES</varname> field, when an
executable and a library are built in the same directory.
</para>
<para>
The reason why winemaker also links with libraries in the Unix sense
in the case above is because functions will not be properly exported.
Once you have exported all the functions in the library's spec file
you should remove them from the <varname>LIBRARIES</varname> field.
</para>
<programlisting>
hello_OBJS = $(hello_C_SRCS:.c=.o) \
$(hello_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_C_SRCS)
CXX_SRCS = $(hello_CXX_SRCS)
RC_SRCS = $(hello_RC_SRCS)
SPEC_SRCS = $(hello_SPEC_SRCS)
</programlisting>
<para>
This section builds 'summary' lists of source files. These lists are
used by the <filename>Make.rules</filename> file.
</para>
<programlisting>
### Generic autoconf targets
all: $(DLLS) $(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 -e 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>
<sect2 id="Make.rules.in">
<title id="Make.rules.in.title">The Make.rules.in file</title>
<para>
What's in the Make.rules.in...
</para>
</sect2>
<sect2 id="configure.in">
<title id="configure.in.title">The configure.in file</title>
<para>
What's in the configure.in...
</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>
</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>
name hello
type win32
mode guiexe
init WinMain
rsrc resource.res
import winmm.dll
</screen>
<para>
And here are the entries you will probably want to change:
</para>
<variablelist>
<varlistentry>
<term>name</term>
<listitem>
<para>
This is the name of the Win32 module. Usually this is the
same as that of the application or library (but without the
'lib' and the '.so').
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>mode</term>
<term>init</term>
<listitem>
<para>
<literal>mode</literal> defines whether what you are
building is a library, <literal>dll</literal>, a console
application, <literal>cuiexe</literal> or a regular
graphical application <literal>guiexe</literal>. Then
<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>import</term>
<listitem>
<para>
Add an 'import' statement for each library that this
executable depends on. If you don't, these libraries will
not get initialized in which case they may very well not
work (e.g. winmm).
</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>
<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>
<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>
(Extracted from tools/winebuild/README)
<!-- FIXME: this seems to be rather outdated and sometimes even incorrect, check with the source! -->
</para>
<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>
name NAME
type win16|win32 &lt;--- the |'s mean it's one or the other
</programlisting>
<para>
These two fields are mandatory. <literal>name</literal>
defines the name of your module and <literal>type</literal>
whether it is a Win16 or Win32 module. Note that for Winelib
you should only be using Win32 modules.
</para>
<programlisting>
file WINFILENAME
</programlisting>
<para>
This field is optional. It gives the name of the Windows file that
is replaced by the builtin. <literal>&lt;name&gt;.DLL</literal>
is assumed if none is given. This is important for kernel, which
lives in the Windows file <filename>KRNL386.EXE</filename>.
</para>
<programlisting>
heap SIZE
</programlisting>
<para>
This field is optional and specific to Win16 modules. It defines
the size of the module local heap. The default is no local heap.
</para>
<programlisting>
mode dll|cuiexe|guiexe
</programlisting>
<para>
This field is optional. It specifies specifies whether it is the
spec file for a dll or the main exe. This is only valid for Win32
spec files.
</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>
import DLL
</programlisting>
<para>
This field can be present zero or more times.
Each instance names a dll that this module depends on (only for
Win32 modules at the present).
</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 preceeded 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
preceeded 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>
</variablelist>
<para>
Only <literal>ptr</literal>, <literal>str</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>
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>
<!-- FIXME: This is outdated -->
<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>
<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>
(Extracted from the HOWTO-Winelib written by Wilbur Dale
&lt;wilbur.dale@lumin.nl&gt;)
</para>
<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>
Well, let's try to have a look at the situation anyway.
</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 compile
your program and if you will be distributing it. For example, if you
are releasing your code under the GPL, you cannot link your code to
MFC code because the GPL requires that you provide ALL sources to your
users. The MFC license forbids you from distributing the MFC source so
you cannot both distribute your program and comply with the GPL
license. On the other hand, if your code is released under the LGPL,
you cannot statically link your program to the MFC and distribute it,
but you can dynamically link your LGPL code and the MFC library and
distribute it.
</para>
<para>
Wine/Winelib is distributed under an X11-like license. It places few
restrictions on the use and distribution of Wine/Winelib code. I doubt
the Wine license will cause you any problems. 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 can not
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>
Things to disable,
why we have to disable them (lack of Wine support),
where things don't compile,
why,
how to solve it,
what to put in the Makefile,
maybe try to point to a place with a ready-made makefile...
</para>
</sect1>
<sect1 id="mfc-using">
<title id="mfc-using.title">Using the MFC</title>
<para>
</para>
<para>
Specific winemaker options,
the configure options,
the initialization problem...
</para>
</sect1>
</chapter>
<chapter id="bindlls">
<title id="bindlls.title">Dealing with binary only dlls</title>
<sect1 id="bindlls-intro">
<title id="binary-dlls-intro.title">Introduction</title>
<para>
describe the problem,
use an example and reuse it in the following sections...
</para>
</sect1>
<sect1 id="bindlls-spec">
<title id="bindlls-spec.title">Writing the spec file</title>
<para>
give an example...
</para>
</sect1>
<sect1 id="bindlls-cxx-apis">
<title id="bindlls-cxx-apis.title">How to deal with C++ APIs</title>
<para>
names are mangled, how to demangle them, how to call them
</para>
</sect1>
<sect1 id="bindlls-wrapper">
<title id="bindlls-wrapper.title">Writing the wrapper</title>
<para>
give an example
</para>
</sect1>
</chapter>
<chapter id="packaging">
<title id="packaging.title">Packaging your Winelib application</title>
<para>
Selecting which libraries to deliver,
how to avoid interference with other Winelib applications,
how to play nice with other Winelib applications
</para>
</chapter>
</book>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-parent-document:("wine-doc.sgml" "set" "book" "")
End:
-->
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment