Commit e86389e0 authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard

Reorganizing wine-devel:

- killing the advanced part (and moving its chapters in both developing Wine and Wine archi parts) - creating a new book on coding practices from i18n.sgml, patches.sgml and porting.sgml - creating a new book on some debugging strategies from the old advanced book and cvs-regression.sgml - creating a new book on the kernel modules (NTDLL & KERNEL32) from architecture.sgml / related DLLs and address-space.sgml, console.sgml, threading.sgml - creating a new book on the windowing from architecture.sgml / USER32 and related - creating a new book on the graphical parts from architecture.sgml / GDI32 and related Other changes: - removed list of DLLs and their role (from the modules overview) - removed in X11 keyboard mapping section the part related to submit a patch
parent 0e3c524f
...@@ -26,20 +26,20 @@ WINE_USER_SRCS = \ ...@@ -26,20 +26,20 @@ WINE_USER_SRCS = \
WINE_DEVEL_SRCS = \ WINE_DEVEL_SRCS = \
address-space.sgml \ address-space.sgml \
architecture.sgml \ architecture.sgml \
consoles.sgml \
cvs-regression.sgml \
ddraw.sgml \ ddraw.sgml \
debugger.sgml \ debugger.sgml \
debugging.sgml \ debugging.sgml \
documentation.sgml \ documentation.sgml \
i18n.sgml \
implementation.sgml \
multimedia.sgml \ multimedia.sgml \
ole.sgml \ ole.sgml \
opengl.sgml \ opengl.sgml \
patches.sgml \ patches.sgml \
porting.sgml \ testing.sgml \
testing.sgml winedev-coding.sgml \
winedev-graphical.sgml \
winedev-kernel.sgml \
winedev-otherdebug.sgml \
winedev-windowing.sgml
WINELIB_USER_SRCS = \ WINELIB_USER_SRCS = \
winelib-bindlls.sgml \ winelib-bindlls.sgml \
......
<chapter id="consoles">
<title>Consoles in Wine</title>
<para>
As described in the Wine User Guide's CUI section, Wine
manipulates three kinds of "consoles" in order to support
properly the Win32 CUI API.
</para>
<para>
The following table describes the main implementation
differences between the three approaches.
<table>
<title>Function consoles implementation comparison</title>
<tgroup cols="4" align="left">
<thead>
<row>
<entry>Function</entry>
<entry>Bare streams</entry>
<entry>Wineconsole &amp; user backend</entry>
<entry>Wineconsole &amp; curses backend</entry>
</row>
</thead>
<tbody>
<row>
<entry>
Console as a Win32 Object (and associated
handles)
</entry>
<entry>
No specific Win32 object is used in this case. The
handles manipulated for the standard Win32 streams
are in fact "bare handles" to their corresponding
Unix streams. The mode manipulation functions
(<function>GetConsoleMode</function> /
<function>SetConsoleMode</function>) are not
supported.
</entry>
<entry>
Implemented in server, and a specific Winelib
program (wineconsole) is in charge of the
rendering and user input. The mode manipulation
functions behave as expected.
</entry>
<entry>
Implemented in server, and a specific Winelib
program (wineconsole) is in charge of the
rendering and user input. The mode manipulation
functions behave as expected.
</entry>
</row>
<row>
<entry>
Inheritance (including handling in
<function>CreateProcess</function> of
<constant>CREATE_DETACHED</constant>,
<constant>CREATE_NEW_CONSOLE</constant> flags).
</entry>
<entry>
Not supported. Every process child of a process
will inherit the Unix streams, so will also
inherit the Win32 standard streams.
</entry>
<entry>
Fully supported (each new console creation will be
handled by the creation of a new USER32 window)
</entry>
<entry>
Fully supported, except for the creation of a new
console, which will be rendered on the same Unix
terminal as the previous one, leading to
unpredictable results.
</entry>
</row>
<row>
<entry><function>ReadFile</function> / <function>WriteFile</function> operations</entry>
<entry>Fully supported</entry>
<entry>Fully supported</entry>
<entry>Fully supported</entry>
</row>
<row>
<entry>
Screen-buffer manipulation (creation, deletion, resizing...)
</entry>
<entry>Not supported</entry>
<entry>Fully supported</entry>
<entry>
Partly supported (this won't work too well as we
don't control (so far) the size of underlying Unix
terminal
</entry>
</row>
<row>
<entry>
APIs for reading/writing screen-buffer content,
cursor position
</entry>
<entry>Not supported</entry>
<entry>Fully supported</entry>
<entry>Fully supported</entry>
</row>
<row>
<entry>
APIs for manipulating the rendering window size
</entry>
<entry>Not supported</entry>
<entry>Fully supported</entry>
<entry>
Partly supported (this won't work too well as we
don't control (so far) the size of underlying Unix
terminal
</entry>
</row>
<row>
<entry>
Signaling (in particular, Ctrl-C handling)
</entry>
<entry>
Nothing is done, which means that Ctrl-C will
generate (as usual) a <constant>SIGINT</constant>
which will terminate the program.
</entry>
<entry>
Partly supported (Ctrl-C behaves as expected,
however the other Win32 CUI signaling isn't
properly implemented).
</entry>
<entry>
Partly supported (Ctrl-C behaves as expected,
however the other Win32 CUI signaling isn't
properly implemented).
</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
<para>
The Win32 objects behind a console can be created in several occasions:
<itemizedlist>
<listitem>
<para>
When the program is started from wineconsole, a new
console object is created and will be used (inherited)
by the process launched from wineconsole.
</para>
</listitem>
<listitem>
<para>
When a program, which isn't attached to a console, calls
<function>AllocConsole</function>, Wine then launches
wineconsole, and attaches the current program to this
console. In this mode, the USER32 mode is always
selected as Wine cannot tell the current state of the
Unix console.
</para>
</listitem>
</itemizedlist>
</para>
<para>
Please also note, that starting a child process with the
<constant>CREATE_NEW_CONSOLE</constant> flag, will end-up
calling <function>AllocConsole</function> in the child
process, hence creating a wineconsole with the USER32 backend.
</para>
</chapter>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-parent-document:("wine-devel.sgml" "set" "book" "part" "chapter" "")
End:
-->
<chapter id="cvs-regression">
<title>How to do regression testing using CVS</title>
<para>
A problem that can happen sometimes is 'it used to work
before, now it doesn't anymore...'. Here is a step by step
procedure to try to pinpoint when the problem occurred. This is
<emphasis>NOT</emphasis> for casual users.
</para>
<orderedlist>
<listitem>
<para>
Get the <quote>full CVS</quote> archive from winehq. This archive is
the CVS tree but with the tags controlling the versioning
system. It's a big file (> 40 meg) with a name like
full-cvs-&lt;last update date> (it's more than 100mb
when uncompressed, you can't very well do this with
small, old computers or slow Internet connections).
</para>
</listitem>
<listitem>
<para>
untar it into a repository directory:
<screen>
cd /home/gerard
tar -zxf full-cvs-2003-08-18.tar.gz
mv wine repository
</screen>
</para>
</listitem>
<listitem>
<para>
extract a new destination directory. This directory must
not be in a subdirectory of the repository else
<command>cvs</command> will think it's part of the
repository and deny you an extraction in the repository:
<screen>
cd /home/gerard
mv wine wine_current (-> this protects your current wine sandbox, if any)
export CVSROOT=/home/gerard/repository
cvs -d $CVSROOT checkout wine
</screen>
</para>
<para>
Note that it's not possible to do a checkout at a given
date; you always do the checkout for the last date where
the full-cvs-xxx snapshot was generated.
</para>
<para>
Note also that it is possible to do all this with a direct
CVS connection, of course. The full CVS file method is less
painful for the WineHQ CVS server and probably a bit faster
if you don't have a very good net connection.
</para>
</listitem>
<listitem>
<para>
you will have now in the <filename>~/wine</filename>
directory an image of the CVS tree, on the client side.
Now update this image to the date you want:
<screen>
cd /home/gerard/wine
cvs update -PAd -D "2004-08-23 CDT"
</screen>
</para>
<para>
The date format is <literal>YYYY-MM-DD HH:MM:SS</literal>.
Using the CST date format ensure that you will be able to
extract patches in a way that will be compatible with the
wine-cvs archive
<ulink url="http://www.winehq.org/hypermail/wine-cvs">
http://www.winehq.org/hypermail/wine-cvs</ulink>
</para>
<para>
Many messages will inform you that more recent files have
been deleted to set back the client cvs tree to the date
you asked, for example:
<screen>
cvs update: tsx11/ts_xf86dga2.c is no longer in the repository
</screen>
</para>
<para>
<command>cvs update</command> is not limited to upgrade to
a <emphasis>newer</emphasis> version as I have believed for
far too long :-(
</para>
</listitem>
<listitem>
<para>
Now proceed as for a normal update:
</para>
<screen>
./configure
make depend && make
</screen>
<para>
If any non-programmer reads this, the fastest method to get
at the point where the problem occurred is to use a binary
search, that is, if the problem occurred in 1999, start at
mid-year, then is the problem is already here, back to 1st
April, if not, to 1st October, and so on.
</para>
<para>
If you have lot of hard disk free space (a full compile currently
takes 400 Mb), copy the oldest known working version before
updating it, it will save time if you need to go back. (it's
better to <command>make distclean</command> before going back in
time, so you have to make everything if you don't backup the older
version)
</para>
<para>
When you have found the day where the problem happened, continue
the search using the wine-cvs archive (sorted by date) and a
more precise cvs update including hour, minute, second :
<screen>
cvs update -PAd -D "2004-08-23 15:17:25 CDT"
</screen>
This will allow you to find easily the exact patch that did it.
</para>
</listitem>
<listitem>
<para>
If you find the patch that is the cause of the problem, you have
almost won; report about it to
<ulink url="http://bugs.winehq.org/">Wine Bugzilla</ulink>
or subscribe to wine-devel and post it there. There is a chance
that the author
will jump in to suggest a fix; or there is always the possibility
to look hard at the patch until it is coerced to reveal where is
the bug :-)
</para>
</listitem>
</orderedlist>
</chapter>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-parent-document:("wine-devel.sgml" "set" "book" "part" "chapter" "")
End:
-->
<chapter id="i18n">
<title>Internationalization</title>
<sect1 id="adding-languages">
<title>Adding New Languages</title>
<para>
This file documents the necessary procedure for adding a new
language to the list of languages that Wine can display system
menus and forms in. Adding new translations is not hard as
it requires no programming knowledge or special skills.
</para>
<para>
Language dependent resources reside in files
named <filename>somefile_Xx.rc</filename> or
<filename>Xx.rc</filename>, where <literal>Xx</literal>
is your language abbreviation (look for it in
<filename>include/winnls.h</filename>). These are included
in a master file named <filename>somefile.rc</filename> or
<filename>rsrc.rc</filename>, located in the same
directory as the language files.
</para>
<para>
To add a new language to one of these resources you
need to make a copy of the English resource (located
in the <filename>somefile_En.rc</filename> file) over to
your <filename>somefile_Xx.rc</filename> file, include this
file in the master <filename>somefile.rc</filename> file,
and edit the new file to translate the English text.
You may also need to rearrange some of the controls
to better fit the newly translated strings. Test your changes
to make sure they properly layout on the screen.
</para>
<para>
In menus, the character "&amp;" means that the next
character will be highlighted and that pressing that
letter will select the item. You should place these
"&amp;" characters suitably for your language, not just
copy the positions from English. In particular,
items within one menu should have different highlighted
letters.
</para>
<para>
To get a list of the files that need translating,
run the following command in the root of your Wine tree:
<command>find -name "*En.rc"</command>.
</para>
<para>
When adding a new language, also make sure the parameters
defined in <filename>./dlls/kernel/nls/*.nls</filename>
fit your local habits and language.
</para>
</sect1>
</chapter>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-parent-document:("wine-devel.sgml" "set" "book" "part" "chapter" "")
End:
-->
<chapter id="porting">
<title>Porting Wine to new Platforms</title>
<para>
This document provides a few tips on porting Wine to your
favorite (UNIX-based) operating system.
</para>
<sect1 id="wine-porting">
<title>Porting Wine to new Platforms</title>
<sect2>
<title>Why <symbol>#ifdef MyOS</symbol> is probably a mistake.</title>
<para>
Operating systems change. Maybe yours doesn't have the
<filename>foo.h</filename> header, but maybe a future
version will have it. If you want to <symbol>#include
&lt;foo.h&gt;</symbol>, it doesn't matter what operating
system you are using; it only matters whether
<filename>foo.h</filename> is there.
</para>
<para>
Furthermore, operating systems change names or "fork" into
several ones. An <symbol>#ifdef MyOs</symbol> will break
over time.
</para>
<para>
If you use the feature of <command>autoconf</command> -- the
Gnu auto-configuration utility -- wisely, you will help
future porters automatically because your changes will test
for <emphasis>features</emphasis>, not names of operating
systems. A feature can be many things:
</para>
<itemizedlist>
<listitem>
<para>
existence of a header file
</para>
</listitem>
<listitem>
<para>
existence of a library function
</para>
</listitem>
<listitem>
<para>
existence of libraries
</para>
</listitem>
<listitem>
<para>
bugs in header files, library functions, the compiler, ...
</para>
</listitem>
</itemizedlist>
<para>
You will need Gnu Autoconf, which you can get from your
friendly Gnu mirror. This program takes Wine's
<filename>configure.ac</filename> file and produces a
<filename>configure</filename> shell script that users use
to configure Wine to their system.
</para>
<para>
There <emphasis>are</emphasis> exceptions to the "avoid
<symbol>#ifdef MyOS</symbol>" rule. Wine, for example, needs
the internals of the signal stack -- that cannot easily be
described in terms of features. Moreover, you can not use
<filename>autoconf</filename>'s <symbol>HAVE_*</symbol>
symbols in Wine's headers, as these may be used by Winelib
users who may not be using a <filename>configure</filename>
script.
</para>
<para>
Let's now turn to specific porting problems and how to solve
them.
</para>
</sect2>
<sect2>
<title>MyOS doesn't have the <filename>foo.h</filename> header!</title>
<para>
This first step is to make <command>autoconf</command> check
for this header. In <filename>configure.in</filename> you
add a segment like this in the section that checks for
header files (search for "header files"):
</para>
<programlisting>
AC_CHECK_HEADER(foo.h, AC_DEFINE(HAVE_FOO_H))
</programlisting>
<para>
If your operating system supports a header file with the
same contents but a different name, say
<filename>bar.h</filename>, add a check for that also.
</para>
<para>
Now you can change
</para>
<programlisting>
#include &lt;foo.h&gt;
</programlisting>
<para>
to
</para>
<programlisting>
#ifdef HAVE_FOO_H
#include &lt;foo.h&gt;
#elif defined (HAVE_BAR_H)
#include &lt;bar.h&gt;
#endif
</programlisting>
<para>
If your system doesn't have a corresponding header file even
though it has the library functions being used, you might
have to add an <symbol>#else</symbol> section to the
conditional. Avoid this if you can.
</para>
<para>
You will also need to add <symbol>#undef HAVE_FOO_H</symbol>
(etc.) to <filename>include/config.h.in</filename>
</para>
<para>
Finish up with <command>make configure</command> and
<command>./configure</command>.
</para>
</sect2>
<sect2>
<title>MyOS doesn't have the <function>bar</function> function!</title>
<para>
A typical example of this is the
<function>memmove</function> function. To solve this
problem you would add <function>memmove</function> to the
list of functions that <command>autoconf</command> checks
for. In <filename>configure.in</filename> you search for
<function>AC_CHECK_FUNCS</function> and add
<function>memmove</function>. (You will notice that someone
already did this for this particular function.)
</para>
<para>
Secondly, you will also need to add <symbol>#undef
HAVE_BAR</symbol> to
<filename>include/config.h.in</filename>
</para>
<para>
The next step depends on the nature of the missing function.
</para>
<variablelist>
<varlistentry>
<term>Case 1:</term>
<listitem>
<para>
It's easy to write a complete implementation of the
function. (<function>memmove</function> belongs to
this case.)
</para>
<para>
You add your implementation in
<filename>misc/port.c</filename> surrounded by
<symbol>#ifndef HAVE_MEMMOVE</symbol> and
<symbol>#endif</symbol>.
</para>
<para>
You might have to add a prototype for your function.
If so, <filename>include/miscemu.h</filename> might be the place. Don't
forget to protect that definition by <symbol>#ifndef
HAVE_MEMMOVE</symbol> and <symbol>#endif</symbol> also!
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Case 2:</term>
<listitem>
<para>
A general implementation is hard, but Wine is only
using a special case.
</para>
<para>
An example is the various <function>wait</function>
calls used in <function>SIGNAL_child</function> from
<filename>loader/signal.c</filename>. Here we have a
multi-branch case on features:
</para>
<programlisting>
#ifdef HAVE_THIS
...
#elif defined (HAVE_THAT)
...
#elif defined (HAVE_SOMETHING_ELSE)
...
#endif
</programlisting>
<para>
Note that this is very different from testing on
operating systems. If a new version of your operating
systems comes out and adds a new function, this code
will magically start using it.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
Finish up with <command>make configure</command> and
<command>./configure</command>.
</para>
</sect2>
</sect1>
</chapter>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-parent-document:("wine-devel.sgml" "set" "book" "part" "chapter" "")
End:
-->
<!doctype book PUBLIC "-//OASIS//DTD DocBook V3.1//EN" [ <!doctype book PUBLIC "-//OASIS//DTD DocBook V3.1//EN" [
<!entity debugger SYSTEM "debugger.sgml"> <!entity debugger SYSTEM "debugger.sgml">
<!entity documentation SYSTEM "documentation.sgml"> <!entity debugging SYSTEM "debugging.sgml">
<!entity patches SYSTEM "patches.sgml"> <!entity otherdebug SYSTEM "winedev-otherdebug.sgml">
<!entity codingpractice SYSTEM "winedev-coding.sgml">
<!entity testing SYSTEM "testing.sgml"> <!entity testing SYSTEM "testing.sgml">
<!entity i18n SYSTEM "i18n.sgml"> <!entity documentation SYSTEM "documentation.sgml">
<!entity architecture SYSTEM "architecture.sgml"> <!entity architecture SYSTEM "architecture.sgml">
<!entity debugging SYSTEM "debugging.sgml"> <!entity kernel SYSTEM "winedev-kernel.sgml">
<!entity graphical SYSTEM "winedev-graphical.sgml">
<!entity windowing SYSTEM "winedev-windowing.sgml">
<!entity ole SYSTEM "ole.sgml"> <!entity ole SYSTEM "ole.sgml">
<!entity opengl SYSTEM "opengl.sgml"> <!entity opengl SYSTEM "opengl.sgml">
<!entity ddraw SYSTEM "ddraw.sgml"> <!entity ddraw SYSTEM "ddraw.sgml">
<!entity multimedia SYSTEM "multimedia.sgml"> <!entity multimedia SYSTEM "multimedia.sgml">
<!entity threading SYSTEM "threading.sgml">
<!entity address-space SYSTEM "address-space.sgml">
<!entity implementation SYSTEM "implementation.sgml">
<!entity porting SYSTEM "porting.sgml">
<!entity consoles SYSTEM "consoles.sgml">
<!entity cvs-regression SYSTEM "cvs-regression.sgml">
]> ]>
...@@ -114,31 +110,23 @@ ...@@ -114,31 +110,23 @@
<title>Developing Wine</title> <title>Developing Wine</title>
&debugger; &debugger;
&documentation; &debugging;
&patches; &otherdebug;
&codingpractice;
&testing; &testing;
&i18n; &documentation;
</part> </part>
<part id="part-two"> <part id="part-two">
<title>Wine Architecture</title> <title>Wine Architecture</title>
&architecture; &architecture;
&debugging; &kernel;
&graphical;
&windowing;
&ole; &ole;
&opengl; &opengl;
&ddraw; &ddraw;
&multimedia; &multimedia;
&threading;
</part> </part>
<part id="part-three">
<title>Advanced Topics</title>
&implementation;
&porting;
&consoles;
&address-space;
&cvs-regression;
</part>
</book> </book>
<chapter>
<title>Graphical modules</title>
<sect1>
<title>GDI Module</title>
<sect2>
<title>X Windows System interface</title>
<para>
The X libraries used to implement X clients (such as Wine)
do not work properly if multiple threads access the same
display concurrently. It is possible to compile the X
libraries to perform their own synchronization (initiated
by calling <function>XInitThreads()</function>). However,
Wine does not use this approach. Instead Wine performs its
own synchronization using the
<function>wine_tsx11_lock()</function> / <function>wine_tsx11_unlock()</function>
functions. This locking protects library access
with a critical section, and also arranges things so that
X libraries compiled without <option>-D_REENTRANT</option>
(eg. with global <varname>errno</varname> variable) will
work with Wine.
</para>
<para>
In the past, all calls to X used to go through a wrapper called
<function>TSX...()</function> (for "Thread Safe X ...").
While it is still being used in the code, it's inefficient
as the lock is potentially aquired and released unnecessarily.
New code should explicitly aquire the lock.
</para>
</sect2>
</sect1>
</chapter>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-parent-document:("wine-devel.sgml" "set" "book" "part" "chapter" "")
End:
-->
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