Reorganizing wine-devel:
authorEric Pouech <pouech-eric@wanadoo.fr>
Tue, 26 Oct 2004 22:45:47 +0000 (22:45 +0000)
committerAlexandre Julliard <julliard@winehq.org>
Tue, 26 Oct 2004 22:45:47 +0000 (22:45 +0000)
- 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

13 files changed:
documentation/Makefile.in
documentation/architecture.sgml
documentation/consoles.sgml [deleted file]
documentation/cvs-regression.sgml [deleted file]
documentation/i18n.sgml [deleted file]
documentation/implementation.sgml [deleted file]
documentation/porting.sgml [deleted file]
documentation/wine-devel.sgml
documentation/winedev-coding.sgml [new file with mode: 0644]
documentation/winedev-graphical.sgml [new file with mode: 0644]
documentation/winedev-kernel.sgml [new file with mode: 0644]
documentation/winedev-otherdebug.sgml [new file with mode: 0644]
documentation/winedev-windowing.sgml [new file with mode: 0644]

index f80417e7b2103da305970b277179390e92c390f0..bbabb82b1be148732b71e683801574e0cac4e1ae 100644 (file)
@@ -26,20 +26,20 @@ WINE_USER_SRCS = \
 WINE_DEVEL_SRCS = \
        address-space.sgml \
        architecture.sgml \
-       consoles.sgml \
-       cvs-regression.sgml \
        ddraw.sgml \
        debugger.sgml \
        debugging.sgml \
        documentation.sgml \
-       i18n.sgml \
-       implementation.sgml \
        multimedia.sgml \
        ole.sgml \
        opengl.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-bindlls.sgml \
index 66afd02199c762c0352da9e93bfeb6b430c912df..62f9f89426a10261fe257652e0e3249dbbf91aab 100644 (file)
          shared library.
        </para>
       </sect2>
+      <sect2 id="arch-dlls">
+       <title>Wine/Windows DLLs</title>
+
+       <para>
+         This document mainly deals with the status of current DLL
+         support by Wine.  The Wine ini file currently supports
+         settings to change the load order of DLLs.  The load order
+         depends on several issues, which results in different settings
+         for various DLLs.
+       </para>
+
+       <sect3>
+         <title>Pros of Native DLLs</title>
+
+         <para>
+           Native DLLs of course guarantee 100% compatibility for
+           routines they implement. For example, using the native USER
+           DLL would maintain a virtually perfect and Windows 95-like
+           look for window borders, dialog controls, and so on. Using
+           the built-in Wine version of this library, on the other
+           hand, would produce a display that does not precisely mimic
+           that of Windows 95.  Such subtle differences can be
+           engendered in other important DLLs, such as the common
+           controls library COMMCTRL or the common dialogs library
+           COMMDLG, when built-in Wine DLLs outrank other types in load
+           order.
+         </para>
+         <para>
+           More significant, less aesthetically-oriented problems can
+           result if the built-in Wine version of the SHELL DLL is
+           loaded before the native version of this library. SHELL
+           contains routines such as those used by installer utilities
+           to create desktop shortcuts. Some installers might fail when
+           using Wine's built-in SHELL.
+         </para>
+       </sect3>
+
+       <sect3>
+         <title>Cons of Native DLLs</title>
+
+         <para>
+           Not every application performs better under native DLLs. If
+           a library tries to access features of the rest of the system
+           that are not fully implemented in Wine, the native DLL might
+           work much worse than the corresponding built-in one, if at
+           all. For example, the native Windows GDI library must be
+           paired with a Windows display driver, which of course is not
+           present under Intel Unix and Wine.
+         </para>
+         <para>
+           Finally, occasionally built-in Wine DLLs implement more
+           features than the corresponding native Windows DLLs.
+           Probably the most important example of such behavior is the
+           integration of Wine with X provided by Wine's built-in USER
+           DLL. Should the native Windows USER library take load-order
+           precedence, such features as the ability to use the
+           clipboard or drag-and-drop between Wine windows and X
+           windows will be lost.
+         </para>
+       </sect3>
+
+       <sect3>
+         <title>Deciding Between Native and Built-In DLLs</title>
+
+         <para>
+           Clearly, there is no one rule-of-thumb regarding which
+           load-order to use. So, you must become familiar with
+           what specific DLLs do and which other DLLs or features 
+           a given library interacts with, and use this information 
+           to make a case-by-case decision.
+         </para>
+       </sect3>
+
+       <sect3>
+         <title>Load Order for DLLs</title>
+
+         <para>
+           Using the DLL sections from the wine configuration file, the
+           load order can be tweaked to a high degree. In general it is
+           advised not to change the settings of the configuration
+           file. The default configuration specifies the right load
+           order for the most important DLLs.
+         </para>
+         <para>
+           The default load order follows this algorithm: for all DLLs
+           which have a fully-functional Wine implementation, or where
+           the native DLL is known not to work, the built-in library
+           will be loaded first. In all other cases, the native DLL
+           takes load-order precedence.
+         </para>
+         <para>
+           The <varname>DefaultLoadOrder</varname> from the
+           [DllDefaults] section specifies for all DLLs which version
+           to try first. See manpage for explanation of the arguments.
+         </para>
+         <para>
+           The [DllOverrides] section deals with DLLs, which need a
+           different-from-default treatment. 
+         </para>
+         <para>
+           The [DllPairs] section is for DLLs, which must be loaded in
+           pairs. In general, these are DLLs for either 16-bit or
+           32-bit applications. In most cases in Windows, the 32-bit
+           version cannot be used without its 16-bit counterpart. For
+           Wine, it is customary that the 16-bit implementations rely
+           on the 32-bit implementations and cast the results back to
+           16-bit arguments. Changing anything in this section is bound
+           to result in errors.
+         </para>
+         <para>
+           For the future, the Wine implementation of Windows DLL seems
+           to head towards unifying the 16 and 32 bit DLLs wherever
+           possible, resulting in larger DLLs.  They are stored in the
+           <filename>dlls/</filename> subdirectory using the 32-bit
+           name.
+         </para>
+       </sect3>
+      </sect2>
+
       <sect2 id="arch-mem">
        <title>Memory management</title>
        <para>
            Wine is using, the glibc malloc arena and so on.
          </para>
        </sect3>
+
+       <sect3 id="address-space">
+         <title>Laying out the address space</title>
+
+         <para>
+           Up until about the start of 2004, the Linux address space
+           very much resembled the Windows 9x layout: the kernel sat
+           in the top gigabyte, the bottom pages were unmapped to
+           catch null pointer dereferences, and the rest was
+           free. The kernels mmap algorithm was predictable: it would
+           start by mapping files at low addresses and work up from
+           there.
+         </para>
+
+         <para>
+           The development of a series of new low level patches
+           violated many of these assumptions, and resulted in Wine
+           needing to force the Win32 address space layout upon the
+           system. This section looks at why and how this is done.
+         </para>
+
+         <para>
+           The exec-shield patch increases security by randomizing
+           the kernels mmap algorithms. Rather than consistently
+           choosing the same addresses given the same sequence of
+           requests, the kernel will now choose randomized
+           addresses. Because the Linux dynamic linker
+           (ld-linux.so.2) loads DSOs into memory by using mmap, this
+           means that DSOs are no longer loaded at predictable
+           addresses, so making it harder to attack software by using
+           buffer overflows. It also attempts to relocate certain
+           binaries into a special low area of memory known as the
+           ASCII armor so making it harder to jump into them when
+           using string based attacks.
+         </para>
+
+         <para>
+           Prelink is a technology that enhances startup times by
+           precalculating ELF global offset tables then saving the
+           results inside the native binaries themselves. By grid
+           fitting each DSO into the address space, the dynamic
+           linker does not have to perform as many relocations so
+           allowing applications that heavily rely on dynamic linkage
+           to be loaded into memory much quicker. Complex C++
+           applications such as Mozilla, OpenOffice and KDE can
+           especially benefit from this technique.
+         </para>
+
+         <para>
+           The 4G VM split patch was developed by Ingo Molnar. It
+           gives the Linux kernel its own address space, thereby
+           allowing processes to access the maximum addressable
+           amount of memory on a 32-bit machine: 4 gigabytes. It
+           allows people with lots of RAM to fully utilise that in
+           any given process at the cost of performance: the reason
+           behind giving the kernel a part of each processes address
+           space was to avoid the overhead of switching on each
+           syscall.
+         </para>
+
+         <para>
+           Each of these changes alter the address space in a way
+           incompatible with Windows. Prelink and exec-shield mean
+           that the libraries Wine uses can be placed at any point in
+           the address space: typically this meant that a library was
+           sitting in the region that the EXE you wanted to run had
+           to be loaded (remember that unlike DLLs, EXE files cannot
+           be moved around in memory). The 4G VM split means that
+           programs could receive pointers to the top gigabyte of
+           address space which some are not prepared for (they may
+           store extra information in the high bits of a pointer, for
+           instance). In particular, in combination with exec-shield
+           this one is especially deadly as it's possible the process
+           heap could be allocated beyond ADDRESS_SPACE_LIMIT which
+           causes Wine initialization to fail.
+         </para>
+
+         <para>
+           The solution to these problems is for Wine to reserve
+           particular parts of the address space so that areas that
+           we don't want the system to use will be avoided. We later
+           on (re/de)allocate those areas as needed. One problem is
+           that some of these mappings are put in place automatically
+           by the dynamic linker: for instance any libraries that
+           Wine is linked to (like libc, libwine, libpthread etc)
+           will be mapped into memory before Wine even gets
+           control. In order to solve that, Wine overrides the
+           default ELF initialization sequence at a low level and
+           reserves the needed areas by using direct syscalls into
+           the kernel (ie without linking against any other code to
+           do it) before restarting the standard initialization and
+           letting the dynamic linker continue. This is referred to
+           as the preloader and is found in loader/preloader.c.
+         </para>
+
+         <para>
+           Once the usual ELF boot sequence has been completed, some
+           native libraries may well have been mapped above the 3gig
+           limit: however, this doesn't matter as 3G is a Windows
+           limit, not a Linux limit. We still have to prevent the
+           system from allocating anything else above there (like the
+           heap or other DLLs) though so Wine performs a binary
+           search over the upper gig of address space in order to
+           iteratively fill in the holes with MAP_NORESERVE mappings
+           so the address space is allocated but the memory to
+           actually back it is not. This code can be found in libs/wine/mmap.c:reserve_area.
+         </para>
+       </sect3>
       </sect2>
+
       <sect2>
        <title>Processes</title>
        <para>
        </para>
       </sect2>
     </sect1>
-
-    <sect1 id="module-overview">
-      
-      <title>Module Overview</title>
-      <sect2>
-       <title>NTDLL Module</title>
-       <para>
-         NTDLL provides most of the services you'd expect from a
-         kernel.
-       </para>
-       <para>
-         Process and thread management are part of them (even if
-         process management is still mainly done in KERNEL32, unlike
-         NT). A Windows process runs as a Unix process, and a Windows
-         thread runs as a Unix thread.
-       </para>
-       <para>
-         Wine also provide fibers (which is the Windows name of
-         co-routines).
-       </para>
-       <para>
-         Most of the Windows memory handling (Heap, Global and Local
-         functions, virtual memory...) are easily mapped upon their
-         Unix equivalents. Note the NTDLL doesn't know about 16 bit
-         memory, which is only handled in KERNEL32/KRNL386.EXE (and
-         also the DOS routines).
-       </para>
-
-       <sect3>
-         <title>File management</title>
-         <para>
-           Wine uses some configuration in order to map Windows
-           filenames (either defined with drive letters, or as UNC
-           names) to the unix filenames. Wine also uses some
-           incantation so that most of file related APIs can also
-           take full unix names. This is handy when passing filenames
-           on the command line.
-         </para>
-         <para>
-           File handles can be waitable objects, as Windows define
-           them.
-         </para>
-         <para>
-           Asynchronous I/O is implemented on file handles by
-           queueing pseudo APC. They are not real APC in the sense
-           that they have the same priority as the threads in the
-           considered process (while APCs on NT have normally a
-           higher priority). These APCs get called when invoking
-           Wine server (which should lead to correct behavior when the
-           program ends up waiting on some object - waiting always
-           implies calling Wine server).
-         </para>
-         <para>
-           FIXME: this should be enhanced and updated to latest work
-           on FS.
-         </para>
-       </sect3>
-
-       <sect3>
-         <title>Synchronization</title>
-         <para>
-           Most of the synchronization (between threads or processes)
-           is done in Wine server, which handles both the waiting
-           operation (on a single object or a set of objects) and the
-           signaling of objects. 
-         </para>
-       </sect3>
-
-       <sect3>
-         <title>Module (DLL) loading</title>
-         <para>
-           Wine is able to load any NE and PE module. In all cases,
-           the module's binary code is directly executed by the
-           processor.
-         </para>
-       </sect3>
-
-       <sect3>
-         <title>Device management</title>
-         <para>
-           Wine allows usage a wide variety of devices:
-           <itemizedlist>
-             <listitem>
-               <para>
-                 Communication ports are mapped to Unix
-                 communication ports (if they have sufficient
-                 permissions).
-               </para>
-             </listitem>
-             <listitem>
-               <para>
-                 Parallel ports are mapped to Unix parallel ports (if
-                 they have sufficient permissions).
-               </para>
-             </listitem>
-             <listitem>
-               <para>
-                 CDROM: the Windows device I/O control calls are
-                 mapped onto Unix <function>ioctl()</function>.
-               </para>
-             </listitem>
-             <listitem>
-               <para>
-                 Some Win9x VxDs are supported, by rewriting some of
-                 their internal behavior. But this support is
-                 limited. Portable programs to Windows NT shouldn't
-                 need them.
-               </para>
-               <para>
-                 Wine will not support native VxD.
-               </para>
-             </listitem>
-           </itemizedlist>
-         </para>
-       </sect3>
-      </sect2>
-
-      <sect2>
-        <title>KERNEL Module</title>
-
-        <para>
-         FIXME: Needs some content...
-       </para>
-      </sect2>
-
-      <sect2>
-        <title>GDI Module</title>
-
-        <sect3>
-          <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>
-        </sect3>
-      </sect2>
-
-      <sect2>
-        <title>USER Module</title>
-
-        <para>
-          USER implements windowing and messaging subsystems. It also
-          contains code for common controls and for other
-          miscellaneous  stuff (rectangles, clipboard, WNet, etc).
-          Wine USER code is  located in <filename>windows/</filename>,
-          <filename>controls/</filename>, and
-          <filename>misc/</filename> directories.
-        </para>
-
-        <sect3>
-          <title>Windowing subsystem</title>
-
-          <para><filename>windows/win.c</filename></para>
-          <para><filename>windows/winpos.c</filename></para>
-          <para>
-            Windows are arranged into parent/child hierarchy with one
-            common ancestor for all windows (desktop window). Each
-            window structure contains a pointer to the immediate
-            ancestor (parent window if <constant>WS_CHILD</constant>
-            style bit is set), a pointer to the sibling (returned by
-            <function>GetWindow(..., GW_NEXT)</function>), a pointer
-            to the owner  window (set only for popup window if it was
-            created with valid  <varname>hwndParent</varname>
-            parameter), and a pointer to the first child window
-            (<function>GetWindow(.., GW_CHILD)</function>). All popup
-            and non-child windows are therefore placed in the first
-            level of this hierarchy and their ancestor link
-            (<varname>wnd-&gt;parent</varname>) points to the desktop
-            window.
-          </para>
-          <screen>
-   Desktop window                      - root window
-    |     \      `-.
-    |      \        `-.
-   popup -&gt; wnd1  -&gt;  wnd2               - top level windows    
-    |       \   `-.      `-.
-    |        \     `-.      `-.
-   child1  child2 -&gt; child3  child4     - child windows
-          </screen>
-          <para>
-            Horizontal arrows denote sibling relationship, vertical
-            lines - ancestor/child. To summarize, all windows with the
-            same immediate ancestor are sibling windows, all windows
-            which do not have desktop as their immediate ancestor are
-            child windows. Popup windows behave as topmost top-level
-            windows unless they are owned. In this case the only
-            requirement is that they must precede their owners in the
-            top-level sibling list (they are not topmost). Child
-            windows are confined to the client area of their parent
-            windows (client area is where window gets to do its own
-            drawing, non-client area consists of caption, menu,
-            borders, intrinsic scrollbars, and
-            minimize/maximize/close/help buttons). 
-          </para>
-          <para>
-            Another fairly important concept is
-            <firstterm>z-order</firstterm>. It is derived from the
-            ancestor/child hierarchy and is used to determine
-            "above/below" relationship. For instance, in the example
-            above, z-order is
-          </para>
-          <screen>
-child1-&gt;popup-&gt;child2-&gt;child3-&gt;wnd1-&gt;child4-&gt;wnd2-&gt;desktop.
-          </screen>
-          <para>
-            Current  active window ("foreground window" in Win32) is
-            moved to the front of z-order unless its top-level
-            ancestor owns popup windows.
-          </para>
-          <para>
-            All these issues are dealt with (or supposed to be) in
-            <filename>windows/winpos.c</filename> with
-            <function>SetWindowPos()</function> being the primary
-            interface to the window manager.
-          </para>
-          <para>
-            Wine specifics: in default and managed mode each top-level
-            window gets its own X counterpart with desktop window
-            being basically a fake stub. In desktop mode, however,
-            only desktop window has an X window associated with it.
-            Also, <function>SetWindowPos()</function> should
-            eventually be implemented via
-            <function>Begin/End/DeferWindowPos()</function> calls and
-            not the other way around.
-          </para>
-
-          <sect4>
-            <title>Visible region, clipping region and update region</title>
-
-            <para><filename>windows/dce.c</filename></para>
-            <para><filename>windows/winpos.c</filename></para>
-            <para><filename>windows/painting.c</filename></para>
-
-            <screen>
-    ________________________
-   |_________               |  A and B are child windows of C
-   |    A    |______        | 
-   |         |      |       |
-   |---------'      |       |
-   |   |      B     |       |
-   |   |            |       |
-   |   `------------'       |
-   |                   C    |
-   `------------------------'
-            </screen>
-            <para>
-              Visible region determines which part of the window is
-              not obscured by other windows. If a window has the
-              <constant>WS_CLIPCHILDREN</constant> style then all
-              areas below its children are considered invisible.
-              Similarly, if the <constant>WS_CLIPSIBLINGS</constant>
-              bit is in effect then all areas obscured by its siblings
-              are invisible. Child windows are always clipped by the
-              boundaries of their parent windows.
-            </para>
-            <para>
-              B has a <constant>WS_CLIPSIBLINGS</constant> style:
-            </para>
-            <screen>
-   .          ______ 
-   :         |      |
-   |   ,-----'      |
-   |   |      B     | - visible region of B
-   |   |            |
-   :   `------------'
-            </screen>
-            <para>
-              When the program requests a <firstterm>display
-                context</firstterm> (DC) for a window it  can specify
-              an optional clipping region that further restricts the
-              area where the graphics output can appear. This area is
-              calculated as an intersection of the visible region and
-              a clipping region. 
-            </para>
-            <para>
-              Program asked for a DC with a clipping region:
-            </para>
-            <screen>
-          ______
-      ,--|--.   |     .    ,--. 
-   ,--+--'  |   |     :   _:  |
-   |  |   B |   |  =&gt; |  |    | - DC region where the painting will
-   |  |     |   |     |  |    |   be visible
-   `--|-----|---'     :  `----'
-      `-----'
-            </screen>
-            <para>
-              When the window manager detects that some part of the window
-              became visible it adds this area to the update region of this
-              window and then generates <constant>WM_ERASEBKGND</constant> and
-              <constant>WM_PAINT</constant> messages.  In addition,
-              <constant>WM_NCPAINT</constant> message is sent when the
-              uncovered area  intersects a nonclient part of the window.
-              Application must reply to the <constant>WM_PAINT</constant>
-              message by calling the
-              <function>BeginPaint()</function>/<function>EndPaint()</function>
-              pair of functions. <function>BeginPaint()</function> returns a DC
-              that uses accumulated update region as a clipping region. This
-              operation cleans up invalidated area and the window will not
-              receive another <constant>WM_PAINT</constant> until the window
-              manager creates a new update region.
-            </para>
-            <para>
-              A was moved to the left:
-            </para>
-            <screen>
-    ________________________       ...          / C update region
-   |______                  |     :      .___ /
-   | A    |_________        |  =&gt; |   ...|___|..
-   |      |         |       |     |   :  |   |
-   |------'         |       |     |   :  '---' 
-   |   |      B     |       |     |   :      \
-   |   |            |       |     :            \
-   |   `------------'       |                    B update region
-   |                   C    |
-   `------------------------'
-            </screen>
-            <para>
-              Windows maintains a display context cache consisting of
-              entries that include the DC itself, the window to which
-              it belongs, and an optional clipping region (visible
-              region is stored in the DC itself). When an API call
-              changes the state of the window tree, window manager has
-              to go through the DC cache to recalculate visible
-              regions for entries whose windows were involved in the
-              operation. DC entries (DCE) can be either private to the
-              window, or private to the window class, or shared
-              between all windows (Windows 3.1 limits the number of
-              shared DCEs to 5).
-            </para>
-          </sect4>
-        </sect3>
-
-        <sect3>
-          <title>Messaging subsystem</title>
-
-          <para><filename>windows/queue.c</filename></para>
-          <para><filename>windows/message.c</filename></para>
-
-          <para>
-            Each Windows task/thread has its own message queue - this
-            is where it gets messages from. Messages can be:
-            <orderedlist>
-              <listitem>
-                <para>
-                  generated on the fly (<constant>WM_PAINT</constant>,
-                  <constant>WM_NCPAINT</constant>,
-                  <constant>WM_TIMER</constant>)
-                </para>
-              </listitem>
-              <listitem>
-                <para>
-                  created by the system (hardware messages)
-                </para>
-              </listitem>
-              <listitem>
-                <para>
-                  posted by other tasks/threads (<function>PostMessage</function>)
-                </para>
-              </listitem>
-              <listitem>
-                <para>
-                  sent by other tasks/threads (<function>SendMessage</function>)
-                </para>
-              </listitem>
-            </orderedlist>
-          </para>
-          <para>
-            Message priority:
-          </para>
-          <para>
-            First the system looks for sent messages, then for posted
-            messages, then for hardware messages, then it checks if
-            the queue has the "dirty window" bit set, and, finally, it
-            checks for expired timers. See
-            <filename>windows/message.c</filename>.
-          </para>
-          <para>
-            From all these different types of messages, only posted
-            messages go directly into the private message queue.
-            System messages (even in Win95) are first collected in the
-            system message queue and then they either sit there until
-            <function>Get/PeekMessage</function> gets to process them
-            or, as in Win95, if system queue is getting clobbered, a
-            special thread ("raw input thread") assigns them to the
-            private queues. Sent messages are queued separately and
-            the sender sleeps until it gets a reply. Special messages
-            are generated on the fly depending on the window/queue
-            state. If the window update region is not empty, the
-            system sets the <constant>QS_PAINT</constant> bit in the
-            owning queue and eventually this window receives a
-            <constant>WM_PAINT</constant> message
-            (<constant>WM_NCPAINT</constant> too if the update region
-            intersects with the non-client area). A timer event is
-            raised when one of the queue timers expire. Depending on
-            the timer parameters <function>DispatchMessage</function>
-            either calls the callback function or the window
-            procedure. If there are no messages pending the
-            task/thread sleeps until messages appear.
-          </para>
-          <para>
-            There are several tricky moments (open for discussion) - 
-          </para>
-
-          <itemizedlist>
-            <listitem>
-              <para>
-                System message order has to be honored and messages
-                should be processed within correct task/thread
-                context. Therefore when <function>Get/PeekMessage</function> encounters
-                unassigned system message and this message appears not
-                to be for the current task/thread it should either
-                skip it (or get rid of it by moving it into the
-                private message queue of the target task/thread -
-                Win95, AFAIK) and look further or roll back and then
-                yield until this message gets processed when system
-                switches to the correct context (Win16). In the first
-                case we lose correct message ordering, in the second
-                case we have the infamous synchronous system message
-                queue. Here is a post to one of the OS/2 newsgroup I
-                found to be relevant:
-              </para>
-              <blockquote>
-                <attribution>by David Charlap</attribution>
-                <para>
-                  " Here's the problem in a nutshell, and there is no
-                  good solution. Every possible solution creates a
-                  different problem.
-                </para>
-                <para>
-                  With a windowing system, events can go to many
-                  different windows. Most are sent by applications or
-                  by the OS when things relating to that window happen
-                  (like repainting, timers, etc.)
-                </para>
-                <para>
-                  Mouse input events go to the window you click on
-                  (unless some window captures the mouse).
-                </para>
-                <para>
-                  So far, no problem.  Whenever an event happens, you
-                  put a message on the target window's message queue.
-                  Every process has a message queue.  If the process
-                  queue fills up, the messages back up onto the system
-                  queue.
-                </para>
-                <para>
-                  This is the first cause of apps hanging the GUI.  If
-                  an app doesn't handle messages and they back up into
-                  the system queue, other apps can't get any more
-                  messages.  The reason is that the next message in
-                  line can't go anywhere, and the system won't skip
-                  over it.
-                </para>
-                <para>
-                  This can be fixed by making apps have bigger private
-                  message queues. The SIQ fix does this.  PMQSIZE does
-                  this for systems without the SIQ fix.  Applications
-                  can also request large queues on their own.
-                </para>
-                <para>
-                  Another source of the problem, however, happens when
-                  you include keyboard events.  When you press a key,
-                  there's no easy way to know what window the
-                  keystroke message should be delivered to.
-                </para>
-                <para>
-                  Most windowing systems use a concept known as
-                  "focus".  The window with focus gets all incoming
-                  keyboard messages.  Focus can be changed from window
-                  to window by apps or by users clicking on windows.
-                </para>
-                <para>
-                  This is the second source of the problem.  Suppose
-                  window A has focus. You click on window B and start
-                  typing before the window gets focus. Where should
-                  the keystrokes go?  On the one hand, they should go
-                  to A until the focus actually changes to B.  On the
-                  other hand, you probably want the keystrokes to go
-                  to B, since you clicked there first.
-                </para>
-                <para>
-                  OS/2's solution is that when a focus-changing event
-                  happens (like clicking on a window), OS/2 holds all
-                  messages in the system queue until the focus change
-                  actually happens.  This way, subsequent keystrokes
-                  go to the window you clicked on, even if it takes a
-                  while for that window to get focus.
-                </para>
-                <para>
-                  The downside is that if the window takes a real long
-                  time to get focus (maybe it's not handling events,
-                  or maybe the window losing focus isn't handling
-                  events), everything backs up in the system queue and
-                  the system appears hung.
-                </para>
-                <para>
-                  There are a few solutions to this problem.
-                </para>
-                <para>
-                  One is to make focus policy asynchronous.  That is,
-                  focus changing has absolutely nothing to do with the
-                  keyboard.  If you click on a window and start typing
-                  before the focus actually changes, the keystrokes go
-                  to the first window until focus changes, then they
-                  go to the second. This is what X-windows does.
-                </para>
-                <para>
-                  Another is what NT does.  When focus changes,
-                  keyboard events are held in the system message
-                  queue, but other events are allowed through. This is
-                  "asynchronous" because the messages in the system
-                  queue are delivered to the application queues in a
-                  different order from that with which they were
-                  posted.  If a bad app won't handle the "lose focus"
-                  message, it's of no consequence - the app receiving
-                  focus will get its "gain focus" message, and the
-                  keystrokes will go to it.
-                </para>
-                <para>
-                  The NT solution also takes care of the application
-                  queue filling up problem.  Since the system delivers
-                  messages asynchronously, messages waiting in the
-                  system queue will just sit there and the rest of the
-                  messages will be delivered to their apps.
-                </para>
-                <para>
-                  The OS/2 SIQ solution is this:  When a
-                  focus-changing event happens, in addition to
-                  blocking further messages from the application
-                  queues, a timer is started.  When the timer goes
-                  off, if the focus change has not yet happened, the
-                  bad app has its focus taken away and all messages
-                  targeted at that window are skipped.  When the bad
-                  app finally handles the focus change message, OS/2
-                  will detect this and stop skipping its messages.
-                </para>
-
-                <para>
-                  As for the pros and cons:
-                </para>
-                <para>
-                  The X-windows solution is probably the easiest.  The
-                  problem is that users generally don't like having to
-                  wait for the focus to change before they start
-                  typing.  On many occasions, you can type and the
-                  characters end up in the wrong window because
-                  something (usually heavy system load) is preventing
-                  the focus change from happening in a timely manner.
-                </para>
-                <para>
-                  The NT solution seems pretty nice, but making the
-                  system message queue asynchronous can cause similar
-                  problems to the X-windows problem. Since messages
-                  can be delivered out of order, programs must not
-                  assume that two messages posted in a particular
-                  order will be delivered in that same order.  This
-                  can break legacy apps, but since Win32 always had an
-                  asynchronous queue, it is fair to simply tell app
-                  designers "don't do that".  It's harder to tell app
-                  designers something like that on OS/2 - they'll
-                  complain "you changed the rules and our apps are
-                  breaking."
-                </para>
-                <para>
-                  The OS/2 solution's problem is that nothing happens
-                  until you try to change window focus, and then wait
-                  for the timeout.  Until then, the bad app is not
-                  detected and nothing is done."
-                </para>
-              </blockquote>
-            </listitem>
-
-            <listitem>
-              <para>
-                Intertask/interthread
-                <function>SendMessage</function>. The system has to
-                inform the target queue about the forthcoming message,
-                then it has to carry out the context switch and wait
-                until the result is available.  Win16 stores necessary
-                parameters in the queue structure and then calls
-                <function>DirectedYield()</function> function.
-                However, in Win32 there could be  several messages
-                pending sent by preemptively executing threads, and in
-                this case <function>SendMessage</function> has to
-                build some sort of message queue for sent messages.
-                Another issue is what to do with messages sent to the
-                sender when it is blocked inside its own
-                <function>SendMessage</function>. 
-              </para>
-            </listitem>
-          </itemizedlist>
-        </sect3>
-      </sect2>
-    </sect1>
-
-    <sect1 id="arch-dlls">
-      <title>Wine/Windows DLLs</title>
-
-      <para>
-        This document mainly deals with the status of current DLL
-        support by Wine.  The Wine ini file currently supports
-        settings to change the load order of DLLs.  The load order
-        depends on several issues, which results in different settings
-        for various DLLs.
-      </para>
-
-      <sect2>
-        <title>Pros of Native DLLs</title>
-
-        <para>
-          Native DLLs of course guarantee 100% compatibility for
-          routines they implement. For example, using the native USER
-          DLL would maintain a virtually perfect and Windows 95-like
-          look for window borders, dialog controls, and so on. Using
-          the built-in Wine version of this library, on the other
-          hand, would produce a display that does not precisely mimic
-          that of Windows 95.  Such subtle differences can be
-          engendered in other important DLLs, such as the common
-          controls library COMMCTRL or the common dialogs library
-          COMMDLG, when built-in Wine DLLs outrank other types in load
-          order.
-        </para>
-        <para>
-          More significant, less aesthetically-oriented problems can
-          result if the built-in Wine version of the SHELL DLL is
-          loaded before the native version of this library. SHELL
-          contains routines such as those used by installer utilities
-          to create desktop shortcuts. Some installers might fail when
-          using Wine's built-in SHELL.
-        </para>
-      </sect2>
-
-      <sect2>
-        <title>Cons of Native DLLs</title>
-
-        <para>
-          Not every application performs better under native DLLs. If
-          a library tries to access features of the rest of the system
-          that are not fully implemented in Wine, the native DLL might
-          work much worse than the corresponding built-in one, if at
-          all. For example, the native Windows GDI library must be
-          paired with a Windows display driver, which of course is not
-          present under Intel Unix and Wine.
-        </para>
-        <para>
-          Finally, occasionally built-in Wine DLLs implement more
-          features than the corresponding native Windows DLLs.
-          Probably the most important example of such behavior is the
-          integration of Wine with X provided by Wine's built-in USER
-          DLL. Should the native Windows USER library take load-order
-          precedence, such features as the ability to use the
-          clipboard or drag-and-drop between Wine windows and X
-          windows will be lost.
-        </para>
-      </sect2>
-
-      <sect2>
-        <title>Deciding Between Native and Built-In DLLs</title>
-
-        <para>
-          Clearly, there is no one rule-of-thumb regarding which
-          load-order to use. So, you must become familiar with
-         what specific DLLs do and which other DLLs or features 
-         a given library interacts with, and use this information 
-         to make a case-by-case decision.
-        </para>
-
-      </sect2>
-
-      <sect2>
-        <title>Load Order for DLLs</title>
-
-        <para>
-          Using the DLL sections from the wine configuration file, the
-          load order can be tweaked to a high degree. In general it is
-          advised not to change the settings of the configuration
-          file. The default configuration specifies the right load
-          order for the most important DLLs.
-        </para>
-        <para>
-          The default load order follows this algorithm: for all DLLs
-          which have a fully-functional Wine implementation, or where
-          the native DLL is known not to work, the built-in library
-          will be loaded first. In all other cases, the native DLL
-          takes load-order precedence.
-        </para>
-        <para>
-          The <varname>DefaultLoadOrder</varname> from the
-          [DllDefaults] section specifies for all DLLs which version
-          to try first. See manpage for explanation of the arguments.
-        </para>
-        <para>
-          The [DllOverrides] section deals with DLLs, which need a
-          different-from-default treatment. 
-        </para>
-        <para>
-          The [DllPairs] section is for DLLs, which must be loaded in
-          pairs. In general, these are DLLs for either 16-bit or
-          32-bit applications. In most cases in Windows, the 32-bit
-          version cannot be used without its 16-bit counterpart. For
-          Wine, it is customary that the 16-bit implementations rely
-          on the 32-bit implementations and cast the results back to
-          16-bit arguments. Changing anything in this section is bound
-          to result in errors.
-        </para>
-        <para>
-          For the future, the Wine implementation of Windows DLL seems
-          to head towards unifying the 16 and 32 bit DLLs wherever
-          possible, resulting in larger DLLs.  They are stored in the
-          <filename>dlls/</filename> subdirectory using the 32-bit
-          name.
-        </para>
-      </sect2>
-
-      <sect2>
-        <title>Understanding What DLLs Do</title>
-
-        <para>
-          The following list briefly describes each of the DLLs
-          commonly found in Windows whose load order may be modified
-          during the configuration and compilation of Wine.
-        </para>
-        <para>
-          (See also <filename>./DEVELOPER-HINTS</filename> or the
-          <filename>dlls/</filename> subdirectory to see which DLLs
-          are currently being rewritten for Wine)
-        </para>
-
-<!-- FIXME: Should convert this table into a VariableList element -->
-        <screen>
-ADVAPI32.DLL:     32-bit application advanced programming interfaces
-                   like crypto, systeminfo, security and event logging
-AVIFILE.DLL:      32-bit application programming interfaces for the
-                   Audio Video Interleave (AVI) Windows-specific
-                   Microsoft audio-video standard
-COMMCTRL.DLL:     16-bit common controls
-COMCTL32.DLL:     32-bit common controls
-COMDLG32.DLL:     32-bit common dialogs
-COMMDLG.DLL:      16-bit common dialogs
-COMPOBJ.DLL:      OLE 16- and 32-bit compatibility libraries
-CRTDLL.DLL:       Microsoft C runtime
-DCIMAN.DLL:       16-bit
-DCIMAN32.DLL:     32-bit display controls
-DDEML.DLL:        DDE messaging
-D3D*.DLL          DirectX/Direct3D drawing libraries
-DDRAW.DLL:        DirectX drawing libraries
-DINPUT.DLL:       DirectX input libraries
-DISPLAY.DLL:      Display libraries
-DPLAY.DLL, DPLAYX.DLL:  DirectX playback libraries
-DSOUND.DLL:       DirectX audio libraries
-GDI.DLL:          16-bit graphics driver interface
-GDI32.DLL:        32-bit graphics driver interface
-IMAGEHLP.DLL:     32-bit IMM API helper libraries (for PE-executables)
-IMM32.DLL:        32-bit IMM API
-IMGUTIL.DLL:      
-KERNEL32.DLL      32-bit kernel DLL
-KEYBOARD.DLL:     Keyboard drivers
-LZ32.DLL:         32-bit Lempel-Ziv or LZ file compression
-                   used by the installshield installers (???).
-LZEXPAND.DLL:     LZ file expansion; needed for Windows Setup
-MMSYSTEM.DLL:     Core of the Windows multimedia system
-MOUSE.DLL:        Mouse drivers
-MPR.DLL:          32-bit Windows network interface
-MSACM.DLL:        Core of the Addressed Call Mode or ACM system
-MSACM32.DLL:      Core of the 32-bit ACM system
-                   Audio Compression Manager ???
-MSNET32.DLL       32-bit network APIs
-MSVFW32.DLL:      32-bit Windows video system
-MSVIDEO.DLL:      16-bit Windows video system
-OLE2.DLL:         OLE 2.0 libraries
-OLE32.DLL:        32-bit OLE 2.0 components
-OLE2CONV.DLL:     Import filter for graphics files
-OLE2DISP.DLL, OLE2NLS.DLL: OLE 2.1 16- and 32-bit interoperability
-OLE2PROX.DLL:     Proxy server for OLE 2.0
-OLE2THK.DLL:      Thunking for OLE 2.0
-OLEAUT32.DLL      32-bit OLE 2.0 automation
-OLECLI.DLL:       16-bit OLE client
-OLECLI32.DLL:     32-bit OLE client
-OLEDLG.DLL:       OLE 2.0 user interface support
-OLESVR.DLL:       16-bit OLE server libraries
-OLESVR32.DLL:     32-bit OLE server libraries
-PSAPI.DLL:        Proces Status API libraries
-RASAPI16.DLL:     16-bit Remote Access Services libraries
-RASAPI32.DLL:     32-bit Remote Access Services libraries
-SHELL.DLL:        16-bit Windows shell used by Setup
-SHELL32.DLL:      32-bit Windows shell (COM object?)
-TAPI/TAPI32/TAPIADDR:  Telephone API (for Modems)
-W32SKRNL:         Win32s Kernel ? (not in use for Win95 and up!)
-WIN32S16.DLL:     Application compatibility for Win32s
-WIN87EM.DLL:      80387 math-emulation libraries
-WINASPI.DLL:      Advanced SCSI Peripheral Interface or ASPI libraries
-WINDEBUG.DLL      Windows debugger
-WINMM.DLL:        Libraries for multimedia thunking
-WING.DLL:         Libraries required to "draw" graphics
-WINSOCK.DLL:      Sockets APIs
-WINSPOOL.DLL:     Print spooler libraries
-WNASPI32.DLL:     32-bit ASPI libraries
-WSOCK32.DLL:      32-bit sockets APIs
-        </screen>
-      </sect2>
-    </sect1>
   </chapter>
 
-  <chapter id="initialization">
-  <title> The Wine initialization process </title>
-
-  <para>
-    Wine has a rather complex startup procedure, so unlike many programs the best place to begin
-    exploring the code-base is <emphasis>not</emphasis> in fact at the main() function but instead
-    at some of the more straightforward DLLs that exist on the periphery such as MSI, the widget
-    library (in USER and COMCTL32) etc. The purpose of this section is to document and explain how
-    Wine starts up from the moment the user runs "wine myprogram.exe" to the point at which
-    myprogram gets control.
-  </para>
-
-  <sect1>
-    <title> First Steps </title>
-
-    <para>
-      The actual wine binary that the user runs does not do very much, in fact it is only
-      responsible for checking the threading model in use (NPTL vs LinuxThreads) and then invoking
-      a new binary which performs the next stage in the startup sequence. See the threading chapter
-      for more information on this check and why it's necessary. You can find this code in
-      <filename>loader/glibc.c</filename>. The result of this check is an exec of either
-      wine-pthread or wine-kthread, potentially (on Linux) via
-      the <emphasis>preloader</emphasis>. We need to use separate binaries here because overriding
-      the native pthreads library requires us to exploit a property of ELF symbol fixup semantics:
-      it's not possible to do this without starting a new process.
-    </para>
-
-    <para>
-      The Wine preloader is found in <filename>loader/preloader.c</filename>, and is required in
-      order to impose a Win32 style address space layout upon the newly created Win32 process. The
-      details of what this does is covered in the address space layout chapter. The preloader is a
-      statically linked ELF binary which is passed the name of the actual Wine binary to run (either
-      wine-kthread or wine-pthread) along with the arguments the user passed in from the command
-      line. The preloader is an unusual program: it does not have a main() function. In standard ELF
-      applications, the entry point is actually at a symbol named _start: this is provided by the
-      standard gcc infrastructure and normally jumps to <function>__libc_start_main</function> which
-      initializes glibc before passing control to the main function as defined by the programmer.
-    </para>
-
-    <para>
-      The preloader takes control direct from the entry point for a few reasons. Firstly, it is
-      required that glibc is not initialized twice: the result of such behaviour is undefined and
-      subject to change without notice. Secondly, it's possible that as part of initializing glibc,
-      the address space layout could be changed - for instance, any call to malloc will initialize a
-      heap arena which modifies the VM mappings. Finally, glibc does not return to _start at any
-      point, so by reusing it we avoid the need to recreate the ELF bootstrap stack (env, argv,
-      auxiliary array etc).
-    </para>
-
-    <para>
-      The preloader is responsible for two things: protecting important regions of the address
-      space so the dynamic linker does not map shared libraries into them, and once that is done
-      loading the real Wine binary off disk, linking it and starting it up. Normally all this is
-      done automatically by glibc and the kernel but as we intercepted this process by using a
-      static binary it's up to us to restart the process. The bulk of the code in the preloader is
-      about loading wine-[pk]thread and ld-linux.so.2 off disk, linking them together, then
-      starting the dynamic linking process.
-    </para>
-
-    <para>
-      One of the last things the preloader does before jumping into the dynamic linker is scan the
-      symbol table of the loaded Wine binary and set the value of a global variable directly: this
-      is a more efficient way of passing information to the main Wine program than flattening the
-      data structures into an environment variable or command line parameter then unpacking it on
-      the other side, but it achieves pretty much the same thing. The global variable set points to
-      the preload descriptor table, which contains the VMA regions protected by the preloader. This
-      allows Wine to unmap them once the dynamic linker has been run, so leaving gaps we can
-      initialize properly later on.
-    </para>
-
-  </sect1>
-
-  <sect1>
-    <title> Starting the emulator </title>
-
-    <para>
-      The process of starting up the emulator itself is mostly one of chaining through various
-      initializer functions defined in the core libraries and DLLs: libwine, then NTDLL, then kernel32.
-    </para>
-
-    <para>
-      Both the wine-pthread and wine-kthread binaries share a common <function>main</function>
-      function, defined in <filename>loader/main.c</filename>, so no matter which binary is selected
-      after the preloader has run we start here. This passes the information provided by the
-      preloader into libwine and then calls wine_init, defined
-      in <filename>libs/wine/loader.c</filename>. This is where the emulation really starts:
-      <function>wine_init</function> can, with the correct preparation,
-      be called from programs other than the wine loader itself.
-    </para>
-
-    <para>
-      <function>wine_init</function> does some very basic setup tasks such as initializing the
-      debugging infrastructure, yet more address space manipulation (see the information on the
-      4G/4G VM split in the address space chapter), before loading NTDLL - the core of both Wine and
-      the Windows NT series - and jumping to the <function>__wine_process_init</function> function defined
-      in <filename>dlls/ntdll/loader.c</filename>
-    </para>
-
-    <para>
-      This function is responsible for initializing the primary Win32 environment. In thread_init(),
-      it sets up the TEB, the wineserver connection for the main thread and the process heap. See
-      the threading chapter for more information on this.
-    </para>
-
-    <para>
-      Finally, it loads and jumps to <function>__wine_kernel_init</function> in kernel32.dll: this
-      is defined in <filename>dlls/kernel32/process.c</filename>. This is where the bulk of the work
-      is done. The kernel32 initialization code retrieves the startup info for the process from the
-      server, initializes the registry, sets up the drive mapping system and locale data, then
-      begins loading the requested application itself. Each process has a STARTUPINFO block that can
-      be passed into <function>CreateProcess</function> specifying various things like how the first
-      window should be displayed: this is sent to the new process via the wineserver.
-    </para>
-
-    <para>
-      After determining the type of file given to Wine by the user (a Win32 EXE file, a Win16 EXE, a
-      Winelib app etc), the program is loaded into memory (which may involve loading and
-      initializing other DLLs, the bulk of Wines startup code), before control reaches the end of
-      <function>__wine_kernel_init</function>. This function ends with the new process stack being
-      initialized, and start_process being called on the new stack. Nearly there!
-    </para>
-
-    <para>
-      The final element of initializing Wine is starting the newly loaded program
-      itself. <function>start_process</function> sets up the SEH backstop handler, calls
-      <function>LdrInitializeThunk</function> which performs the last part of the process
-      initialization (such as performing relocations and calling the DllMains with PROCESS_ATTACH),
-      grabs the entry point of the executable and then on this line:
-    </para>
-
-    <programlisting>
-      ExitProcess( entry( peb ) );
-    </programlisting>
-
-    <para>
-      ... jumps to the entry point of the program. At this point the users program is running and
-      the API provided by Wine is ready to be used. When entry returns,
-      the <function>ExitProcess</function> API will be used to initialize a graceful shutdown.
-    </para>
-
-  </sect1>
-  </chapter>
 
 <!-- Keep this comment at the end of the file
 Local variables:
diff --git a/documentation/consoles.sgml b/documentation/consoles.sgml
deleted file mode 100644 (file)
index fa420f0..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-  <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:
--->
diff --git a/documentation/cvs-regression.sgml b/documentation/cvs-regression.sgml
deleted file mode 100644 (file)
index a0dbd97..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-  <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:
-  -->
diff --git a/documentation/i18n.sgml b/documentation/i18n.sgml
deleted file mode 100644 (file)
index b2498d3..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-  <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:
--->
diff --git a/documentation/implementation.sgml b/documentation/implementation.sgml
deleted file mode 100644 (file)
index e190f53..0000000
+++ /dev/null
@@ -1,608 +0,0 @@
-  <chapter id="implementation">
-    <title>Low-level Implementation</title>
-    <para>Details of Wine's Low-level Implementation...</para>
-
-<sect1 id="config-keyboard">
-<title>Keyboard</title>
-
-<para>
-Wine now needs to know about your keyboard layout. This
-requirement comes from a need from many apps to have the
-correct scancodes available, since they read these directly,
-instead of just taking the characters returned by the X
-server. This means that Wine now needs to have a mapping from
-X keys to the scancodes these programs expect.
-</para>
-<para>
-On startup, Wine will try to recognize the active X layout by
-seeing if it matches any of the defined tables. If it does,
-everything is alright. If not, you need to define it.
-</para>
-<para>
-To do this, open the file
-<filename>dlls/x11drv/keyboard.c</filename> and take a look
-at the existing tables. Make a backup copy of it, especially
-if you don't use CVS.
-</para>
-<para>
-What you really would need to do, is find out which scancode
-each key needs to generate.  Find it in the
-<function>main_key_scan</function> table, which looks like
-this:
-</para>
-<programlisting>
-static const int main_key_scan[MAIN_LEN] =
-{
-/* this is my (102-key) keyboard layout, sorry if it doesn't quite match yours */
-0x29,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,
-0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,
-0x1E,0x1F,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x2B,
-0x2C,0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,0x35,
-0x56 /* the 102nd key (actually to the right of l-shift) */
-};
-</programlisting>
-<para>
-Next, assign each scancode the characters imprinted on the
-keycaps. This was done (sort of) for the US 101-key keyboard,
-which you can find near the top in
-<filename>keyboard.c</filename>. It also shows that if there
-is no 102nd key, you can skip that.
-</para>
-<para>
-However, for most international 102-key keyboards, we have
-done it easy for you. The scancode layout for these already
-pretty much matches the physical layout in the
-<function>main_key_scan</function>, so all you need to do is
-to go through all the keys that generate characters on your
-main keyboard (except spacebar), and stuff those into an
-appropriate table. The only exception is that the 102nd key,
-which is usually to the left of the first key of the last line
-(usually <keycap>Z</keycap>), must be placed on a separate
-line after the last line.
-</para>
-<para>
-For example, my Norwegian keyboard looks like this
-</para>
-<screen>
-�  !  "  #  �  %  &  /  (  )  =  ?  `  Back-
-|  1  2@ 3� 4$ 5  6  7{ 8[ 9] 0} +  \� space
-
-Tab Q  W  E  R  T  Y  U  I  O  P  �  ^
-                            �~
-                               Enter
-Caps A  S  D  F  G  H  J  K  L  �  �  *
-Lock                                  '
-
-Sh- > Z  X  C  V  B  N  M  ;  :  _  Shift
-ift &lt;                      ,  .  -
-
-Ctrl  Alt       Spacebar       AltGr  Ctrl
-</screen>
-<para>
-Note the 102nd key, which is the <keycap>&lt;></keycap> key, to
-the left of <keycap>Z</keycap>. The character to the right of
-the main character is the character generated by
-<keycap>AltGr</keycap>.
-</para>
-<para>
-This keyboard is defined as follows:
-</para>
-<programlisting>
-static const char main_key_NO[MAIN_LEN][4] =
-{
-"|�","1!","2\"@","3#�","4�$","5%","6&","7/{","8([","9)]","0=}","+?","\\�",
-"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","��","�^~",
-"aA","sS","dD","fF","gG","hH","jJ","kK","lL","��","��","'*",
-"zZ","xX","cC","vV","bB","nN","mM",",;",".:","-_",
-"&lt;>"
-};
-</programlisting>
-<para>
-Except that " and \ needs to be quoted with a backslash, and
-that the 102nd key is on a separate line, it's pretty
-straightforward.
-</para>
-<para>
-After you have written such a table, you need to add it to the
-<function>main_key_tab[]</function> layout index table. This
-will look like this:
-</para>
-<programlisting>
-static struct {
-WORD lang, ansi_codepage, oem_codepage;
-const char (*key)[MAIN_LEN][4];
-} main_key_tab[]={
-...
-...
-{MAKELANGID(LANG_NORWEGIAN,SUBLANG_DEFAULT),  1252, 865, &amp;main_key_NO},
-...
-</programlisting>
-<para>
-After you have added your table, recompile Wine and test that
-it works. If it fails to detect your table, try running
-</para>
-<screen>
-WINEDEBUG=+key,+keyboard wine > key.log 2>&1
-      </screen>
-      <para>
-        and look in the resulting <filename>key.log</filename> file to
-        find the error messages it gives for your layout.
-      </para>
-      <para>
-        Note that the <constant>LANG_*</constant> and
-        <constant>SUBLANG_*</constant> definitions are in
-        <filename>include/winnls.h</filename>, which you might need to
-        know to find out which numbers your language is assigned, and
-        find it in the WINEDEBUG output. The numbers will be
-        <literal>(SUBLANG * 0x400 + LANG)</literal>, so, for example
-        the combination <literal>LANG_NORWEGIAN (0x14)</literal> and
-        <literal>SUBLANG_DEFAULT (0x1)</literal> will be (in hex)
-        <literal>14 + 1*400 = 414</literal>, so since I'm Norwegian, I
-        could look for <literal>0414</literal> in the WINEDEBUG output
-        to find out why my keyboard won't detect.
-      </para>
-      <para>
-        Once it works, submit it to the Wine project. If you use CVS,
-        you will just have to do
-      </para>
-      <screen>
-cvs -z3 diff -u dlls/x11drv/keyboard.c > layout.diff
-      </screen>
-      <para>
-        from your main Wine directory, then submit
-        <filename>layout.diff</filename> to
-        <email>wine-patches@winehq.org</email> along with a brief note
-        of what it is.
-      </para>
-      <para>
-        If you don't use CVS, you need to do
-      </para>
-      <screen>
-diff -u the_backup_file_you_made dlls/x11drv/keyboard.c > layout.diff
-      </screen>
-      <para>
-        and submit it as explained above.
-      </para>
-      <para>
-        If you did it right, it will be included in the next Wine
-        release, and all the troublesome programs (especially
-        remote-control programs) and games that use scancodes will
-        be happily using your keyboard layout, and you won't get those
-        annoying fixme messages either.
-      </para>
-    </sect1>
-
-
-    <sect1 id="undoc-func">
-      <title>Undocumented APIs</title>
-
-       <para>
-         Some background:  On the i386 class of machines, stack entries are
-         usually dword (4 bytes) in size, little-endian.  The stack grows
-         downward in memory.  The stack pointer, maintained in the 
-         <literal>esp</literal> register, points to the last valid entry; 
-         thus, the operation of pushing a value onto the stack involves 
-         decrementing <literal>esp</literal> and then moving the value into 
-         the memory pointed to by <literal>esp</literal>
-         (i.e., <literal>push p</literal> in assembly resembles 
-         <literal>*(--esp) = p;</literal> in C).  Removing (popping)
-         values off the stack is the reverse (i.e., <literal>pop p</literal> 
-         corresponds to <literal>p = *(esp++);</literal> in C).
-       </para>
-
-       <para>
-         In the <literal>stdcall</literal> calling convention, arguments are 
-         pushed onto the stack right-to-left.  For example, the C call
-         <function>myfunction(40, 20, 70, 30);</function> is expressed in 
-         Intel assembly as:
-         <screen>
-    push 30
-    push 70
-    push 20
-    push 40
-    call myfunction
-         </screen>
-         The called function is responsible for removing the arguments 
-         off the stack.  Thus, before the call to myfunction, the
-         stack would look like:
-         <screen>
-             [local variable or temporary]
-             [local variable or temporary]
-              30
-              70
-              20
-    esp ->    40
-         </screen>
-         After the call returns, it should look like:
-         <screen>
-             [local variable or temporary]
-    esp ->   [local variable or temporary]
-         </screen>
-       </para>
-
-       <para>
-         To restore the stack to this state, the called function must know how
-         many arguments to remove (which is the number of arguments it takes).
-         This is a problem if the function is undocumented.
-       </para>
-
-       <para>
-         One way to attempt to document the number of arguments each function
-         takes is to create a wrapper around that function that detects the
-         stack offset.  Essentially, each wrapper assumes that the function will 
-         take a large number of arguments.  The wrapper copies each of these 
-         arguments into its stack, calls the actual function, and then calculates 
-         the number of arguments by checking esp before and after the call.
-       </para>
-
-       <para>
-         The main problem with this scheme is that the function must actually
-         be called from another program.  Many of these functions are seldom
-         used.  An attempt was made to aggressively query each function in a
-         given library (<filename>ntdll.dll</filename>) by passing 64 arguments, 
-         all 0, to each function.  Unfortunately, Windows NT quickly goes to a 
-         blue screen of death, even if the program is run from a 
-         non-administrator account.
-       </para>
-
-       <para>
-         Another method that has been much more successful is to attempt to
-         figure out how many arguments each function is removing from the
-         stack.  This instruction, <literal>ret hhll</literal> (where 
-         <symbol>hhll</symbol> is the number of bytes to remove, i.e. the 
-         number of arguments times 4), contains the bytes 
-         <literal>0xc2 ll hh</literal> in memory.  It is a reasonable
-         assumption that few, if any, functions take more than 16 arguments; 
-         therefore, simply searching for 
-         <literal>hh == 0 && ll &lt; 0x40</literal>  starting from the 
-         address of a function yields the correct number of arguments most 
-         of the time.
-       </para>
-
-       <para>
-         Of course, this is not without errors. <literal>ret 00ll</literal> 
-         is not the only instruction that can have the byte sequence 
-         <literal>0xc2 ll 0x0</literal>; for example, 
-         <literal>push 0x000040c2</literal> has the byte sequence
-         <literal>0x68 0xc2 0x40 0x0 0x0</literal>, which matches 
-         the above.  Properly, the utility should look for this sequence 
-         only on an instruction boundary; unfortunately, finding 
-         instruction boundaries on an i386 requires implementing a full 
-         disassembler -- quite a daunting task.  Besides, the probability 
-         of having such a byte sequence that is not the actual return 
-         instruction is fairly low.
-       </para>
-
-       <para>
-         Much more troublesome is the non-linear flow of a function.  For
-         example, consider the following two functions:
-         <screen>
-    somefunction1:
-        jmp  somefunction1_impl
-
-    somefunction2:
-        ret  0004
-
-    somefunction1_impl:
-        ret  0008
-         </screen>
-         In this case, we would incorrectly detect both 
-         <function>somefunction1</function> and
-         <function>somefunction2</function> as taking only a single 
-         argument, whereas <function>somefunction1</function> really 
-         takes two arguments.
-       </para>
-
-       <para>
-         With these limitations in mind, it is possible to implement more stubs
-         in Wine and, eventually, the functions themselves.
-       </para>
-    </sect1>
-
-    <sect1 id="accel-impl">
-      <title>Accelerators</title>
-
-      <para>
-        There are <emphasis>three</emphasis> differently sized
-        accelerator structures exposed to the user: 
-      </para>
-      <orderedlist>
-        <listitem>
-          <para>
-            Accelerators in NE resources.  This is also the internal
-            layout of the global handle <type>HACCEL</type> (16 and
-            32) in Windows 95 and Wine. Exposed to the user as Win16
-            global handles <type>HACCEL16</type> and
-            <type>HACCEL32</type> by the Win16/Win32 API.
-           These are 5 bytes long, with no padding:
-            <programlisting>
-BYTE   fVirt;
-WORD   key;
-WORD   cmd;
-            </programlisting>
-          </para>
-        </listitem>
-        <listitem>
-          <para>
-            Accelerators in PE resources. They are exposed to the user 
-           only by direct accessing PE resources. 
-           These have a size of 8 bytes:
-          </para>
-          <programlisting>
-BYTE   fVirt;
-BYTE   pad0;
-WORD   key;
-WORD   cmd;
-WORD   pad1;
-          </programlisting>
-        </listitem>
-        <listitem>
-          <para>
-            Accelerators in the Win32 API.  These are exposed to the 
-            user by the  <function>CopyAcceleratorTable</function>
-           and  <function>CreateAcceleratorTable</function> functions
-           in the Win32 API.
-           These have a size of 6 bytes:
-          </para>
-          <programlisting>
-BYTE   fVirt;
-BYTE   pad0;
-WORD   key;
-WORD   cmd;
-          </programlisting>
-        </listitem>
-      </orderedlist>
-
-      <para>
-        Why two types of accelerators in the Win32 API? We can only
-        guess, but my best bet is that the Win32 resource compiler
-        can/does not handle struct packing. Win32 <type>ACCEL</type>
-        is defined using <function>#pragma(2)</function> for the
-        compiler but without any packing for RC, so it will assume
-        <function>#pragma(4)</function>.
-      </para>
-
-    </sect1>
-
-    <sect1 id="hardware-trace">
-      <title>Doing A Hardware Trace</title>
-
-      <para>
-        The primary reason to do this is to reverse engineer a
-        hardware device for which you don't have documentation, but
-        can get to work under Wine.
-      </para>
-      <para>
-        This lot is aimed at parallel port devices, and in particular
-        parallel port scanners which are now so cheap they are
-        virtually being given away. The problem is that few
-        manufactures will release any programming information which
-        prevents drivers being written for Sane, and the traditional
-        technique of using DOSemu to produce the traces does not work
-        as the scanners invariably only have drivers for Windows.
-      </para>
-      <para>
-        Presuming that you have compiled and installed wine the first
-        thing to do is is to enable direct hardware access to your
-        parallel port. To do this edit <filename>config</filename>
-        (usually in <filename>~/.wine/</filename>) and in the
-        ports section add the following two lines
-      </para>
-      <programlisting>
-read=0x378,0x379,0x37a,0x37c,0x77a
-write=0x378,x379,0x37a,0x37c,0x77a
-      </programlisting>
-      <para>
-        This adds the necessary access required for SPP/PS2/EPP/ECP
-        parallel port on LPT1. You will need to adjust these number
-        accordingly if your parallel port is on LPT2 or LPT0.
-      </para>
-      <para>
-        When starting wine use the following command line, where
-        <literal>XXXX</literal> is the program you need to run in
-        order to access your scanner, and <literal>YYYY</literal> is
-        the file your trace will be stored in:
-      </para>
-      <programlisting>
-WINEDEBUG=+io wine XXXX 2&gt; &gt;(sed 's/^[^:]*:io:[^ ]* //' &gt; YYYY)
-      </programlisting>
-      <para>
-        You will need large amounts of hard disk space (read hundreds
-        of megabytes if you do a full page scan), and for reasonable
-        performance a really fast processor and lots of RAM.
-      </para>
-      <para>
-       You will need to postprocess the output into a more manageable
-       format, using the <command>shrink</command> program. First
-        you need to compile the source (which is located at the end of
-       this section):
-      <programlisting>
-cc shrink.c -o shrink
-      </programlisting>
-      </para>
-      <para>
-        Use the <command>shrink</command> program to reduce the
-        physical size of the raw log as follows:
-      </para>
-      <programlisting>
-cat log | shrink &gt; log2
-      </programlisting>
-      <para>
-        The trace has the basic form of
-      </para>
-      <programlisting>
-XXXX &gt; YY @ ZZZZ:ZZZZ
-      </programlisting>
-      <para>
-        where <literal>XXXX</literal> is the port in hexadecimal being
-        accessed, <literal>YY</literal> is the data written (or read)
-        from the port, and <literal>ZZZZ:ZZZZ</literal> is the address
-        in memory of the instruction that accessed the port. The
-        direction of the arrow indicates whether the data was written
-        or read from the port.
-      </para>
-      <programlisting>
-&gt; data was written to the port
-&lt; data was read from the port
-      </programlisting>
-      <para>
-        My basic tip for interpreting these logs is to pay close
-        attention to the addresses of the IO instructions. Their
-        grouping and sometimes proximity should reveal the presence of
-        subroutines in the driver. By studying the different versions
-        you should be able to work them out. For example consider the
-        following section of trace from my UMAX Astra 600P
-      </para>
-      <programlisting>
-0x378 &gt; 55 @ 0297:01ec
-0x37a &gt; 05 @ 0297:01f5
-0x379 &lt; 8f @ 0297:01fa
-0x37a &gt; 04 @ 0297:0211
-0x378 &gt; aa @ 0297:01ec
-0x37a &gt; 05 @ 0297:01f5
-0x379 &lt; 8f @ 0297:01fa
-0x37a &gt; 04 @ 0297:0211
-0x378 &gt; 00 @ 0297:01ec
-0x37a &gt; 05 @ 0297:01f5
-0x379 &lt; 8f @ 0297:01fa
-0x37a &gt; 04 @ 0297:0211
-0x378 &gt; 00 @ 0297:01ec
-0x37a &gt; 05 @ 0297:01f5
-0x379 &lt; 8f @ 0297:01fa
-0x37a &gt; 04 @ 0297:0211
-0x378 &gt; 00 @ 0297:01ec
-0x37a &gt; 05 @ 0297:01f5
-0x379 &lt; 8f @ 0297:01fa
-0x37a &gt; 04 @ 0297:0211
-0x378 &gt; 00 @ 0297:01ec
-0x37a &gt; 05 @ 0297:01f5
-0x379 &lt; 8f @ 0297:01fa
-0x37a &gt; 04 @ 0297:0211
-      </programlisting>
-      <para>
-        As you can see there is a repeating structure starting at
-        address <literal>0297:01ec</literal> that consists of four io
-        accesses on the parallel port. Looking at it the first io
-        access writes a changing byte to the data port the second
-        always writes the byte <literal>0x05</literal> to the control
-        port, then a value which always seems to
-        <literal>0x8f</literal> is read from the status port at which
-        point a byte <literal>0x04</literal> is written to the control
-        port. By studying this and other sections of the trace we can
-        write a C routine that emulates this, shown below with some
-        macros to make reading/writing on the parallel port easier to
-        read.
-      </para>
-      <programlisting>
-#define r_dtr(x)        inb(x)
-#define r_str(x)        inb(x+1)
-#define r_ctr(x)        inb(x+2)
-#define w_dtr(x,y)      outb(y, x)
-#define w_str(x,y)      outb(y, x+1)
-#define w_ctr(x,y)      outb(y, x+2)
-
-/* Seems to be sending a command byte to the scanner */
-int udpp_put(int udpp_base, unsigned char command)
-{
-    int loop, value;
-
-    w_dtr(udpp_base, command);
-    w_ctr(udpp_base, 0x05);
-
-    for (loop=0; loop &lt; 10; loop++)
-        if ((value = r_str(udpp_base)) & 0x80) 
-       {
-            w_ctr(udpp_base, 0x04);
-            return value & 0xf8;
-        }
-
-    return (value & 0xf8) | 0x01;
-}
-      </programlisting>
-      <para>
-        For the UMAX Astra 600P only seven such routines exist (well
-        14 really, seven for SPP and seven for EPP). Whether you
-        choose to disassemble the driver at this point to verify the
-        routines is your own choice. If you do, the address from the
-        trace should help in locating them in the disassembly.
-      </para>
-      <para>
-        You will probably then find it useful to write a script/perl/C
-        program to analyse the logfile and decode them futher as this
-        can reveal higher level grouping of the low level routines.
-        For example from the logs from my UMAX Astra 600P when decoded
-        further reveal (this is a small snippet)
-      </para>
-      <programlisting>
-start:
-put: 55 8f
-put: aa 8f
-put: 00 8f
-put: 00 8f
-put: 00 8f
-put: c2 8f
-wait: ff
-get: af,87
-wait: ff
-get: af,87
-end: cc
-start:
-put: 55 8f
-put: aa 8f
-put: 00 8f
-put: 03 8f
-put: 05 8f
-put: 84 8f
-wait: ff
-      </programlisting>
-      <para>
-        From this it is easy to see that <varname>put</varname>
-        routine is often grouped together in five successive calls
-        sending information to the scanner. Once these are understood
-        it should be possible to process the logs further to show the
-        higher level routines in an easy to see format. Once the
-        highest level format that you can derive from this process is
-        understood, you then need to produce a series of scans varying
-        only one parameter between them, so you can discover how to
-        set the various parameters for the scanner.
-      </para>
-
-      <para>
-        The following is the <filename>shrink.c</filename> program:
-      <programlisting>
-/* Copyright David Campbell &lt;campbell@torque.net&gt; */
-#include &lt;stdio.h&gt;
-#include &lt;string.h&gt;
-
-int main (void)
-{
-    char buff[256], lastline[256] = "";
-    int count = 0;
-
-    while (!feof (stdin))
-    {
-        fgets (buff, sizeof (buff), stdin);
-        if (strcmp (buff, lastline))
-       {
-           if (count &gt; 1)
-               printf ("# Last line repeated %i times #\n", count);
-           printf ("%s", buff);
-           strcpy (lastline, buff);
-           count = 1;
-       }
-        else count++;
-    }
-    return 0;
-}
-      </programlisting>
-      </para>
-    </sect1>
-
-  </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:
--->
diff --git a/documentation/porting.sgml b/documentation/porting.sgml
deleted file mode 100644 (file)
index a732670..0000000
+++ /dev/null
@@ -1,219 +0,0 @@
-  <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:
--->
index 8217b98d6b5c468fb30fbb585cd8dc52614ad94a..c8243a8762cdd9b1e8067371562532132c5640e9 100644 (file)
@@ -1,24 +1,20 @@
 <!doctype book PUBLIC "-//OASIS//DTD DocBook V3.1//EN" [
 
 <!entity debugger SYSTEM "debugger.sgml">
-<!entity documentation SYSTEM "documentation.sgml">
-<!entity patches SYSTEM "patches.sgml">
+<!entity debugging SYSTEM "debugging.sgml">
+<!entity otherdebug SYSTEM "winedev-otherdebug.sgml">
+<!entity codingpractice SYSTEM "winedev-coding.sgml">
 <!entity testing SYSTEM "testing.sgml">
-<!entity i18n SYSTEM "i18n.sgml">
+<!entity documentation SYSTEM "documentation.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 opengl SYSTEM "opengl.sgml">
 <!entity ddraw SYSTEM "ddraw.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">
 
 ]>
 
     <title>Developing Wine</title>
 
     &debugger;
-    &documentation;
-    &patches;
+    &debugging;
+    &otherdebug;
+    &codingpractice;
     &testing;
-    &i18n;
+    &documentation;
   </part>
 
   <part id="part-two">
     <title>Wine Architecture</title>
 
     &architecture;
-    &debugging;
+    &kernel;
+    &graphical;
+    &windowing;
     &ole;
     &opengl;
     &ddraw;
     &multimedia;
-    &threading;
   </part>
-
-  <part id="part-three">
-    <title>Advanced Topics</title>
-    &implementation;
-    &porting;
-    &consoles;
-    &address-space;    
-    &cvs-regression;
-  </part>
-
 </book>
diff --git a/documentation/winedev-coding.sgml b/documentation/winedev-coding.sgml
new file mode 100644 (file)
index 0000000..e8f80cd
--- /dev/null
@@ -0,0 +1,514 @@
+  <chapter id="codingpractice">
+    <title>Coding Practice</title>
+  
+    <para>
+      This chapter describes the relevant coding practices in Wine,
+      that you should be aware of before doing any serious development
+      in Wine.
+    </para>
+    <sect1 id="patch-format">
+      <title>Patch Format</title>
+
+      <para>
+        Patches are submitted via email to the Wine patches mailing
+       list,  <email>wine-patches@winehq.org</email>. Your patch
+       should include: 
+      </para>
+
+      <itemizedlist>
+        <listitem>
+          <para>
+            A meaningful subject (very short description of patch)            
+          </para>
+        </listitem>
+         <listitem>
+          <para>
+            A long (paragraph) description of what was wrong and what
+           is now better. (recommended)
+          </para>
+        </listitem>
+        <listitem>
+          <para>
+            A change log entry (short description of what was
+           changed). 
+          </para>
+        </listitem>
+        <listitem>
+          <para>
+            The patch in <command>diff -u</command> format
+          </para>
+        </listitem>
+      </itemizedlist>
+
+      <para></para>
+
+      <para>
+        <command>cvs diff -u</command> works great for the common case
+       where a file is edited.  However, if you add or remove a file
+        <command>cvs diff</command> will not report that correctly so
+        make sure you explicitly take care of this rare case.
+      </para>
+      <para>
+        For additions simply include them by appending the
+        <command>diff -u /dev/null /my/new/file</command> output of
+       them to any <command>cvs diff -u</command> output you may
+       have. Alternatively, use <command>diff -Nu olddir/
+       newdir/</command> in case of multiple new files to add.
+      </para>
+      <para>
+        For removals, clearly list the files in the description of the
+       patch.
+      </para>
+      <para>
+        Since wine is constantly changing due to development it is
+       strongly recommended that you use cvs for patches, if you
+       cannot use cvs for some reason, you can submit patches against
+       the latest tarball.  To do this make a copy of the files that
+       you will be modifying and <command>diff -u</command> against
+       the old file. I.E. 
+      </para>
+      <screen>
+diff -u file.old file.c > file.txt
+      </screen>
+    </sect1>
+
+    <sect1 id="Style-notes">
+      <title>Some notes about style</title>
+       
+      <para>
+        There are a few conventions that about coding style that have
+       been adopted over the years of development. The rational for
+       these <quote>rules</quote> is explained for each one.
+      </para>
+      <itemizedlist>
+        <listitem>
+         <para>
+           No HTML mail, since patches should be in-lined and HTML
+           turns the patch into garbage. Also it is considered bad
+           etiquette as it  uglifies the message, and is not viewable
+           by many of the subscribers.
+         </para>
+        </listitem>
+       <listitem>
+         <para>
+           Only one change set per patch. Patches should address only
+           one bug/problem at a time. If a lot of changes need to be
+           made then it is preferred to break it into a series of
+           patches. This makes it easier to find regressions.
+         </para>
+        </listitem>
+        <listitem>
+         <para>
+           Tabs are not forbidden but discouraged. A tab is defined
+           as 8 characters and the usual amount of indentation is 4
+           characters.
+         </para>
+        </listitem>
+        <listitem>
+         <para>
+           C++ style comments are discouraged since some compilers
+           choke on  them.
+         </para>
+        </listitem>
+        <listitem>
+         <para>
+           Commenting out a block of code is usually done by
+           enclosing it in  <command>#if 0 ... #endif</command>
+           Statements. For example.
+         </para>
+         <screen> 
+/* note about reason for commenting block */
+#if 0
+code
+code /* comments */
+code
+#endif
+         </screen>
+         <para>
+           The reason for using this method is that it does not
+           require that you edit comments that may be inside the
+           block of code.
+         </para>
+        </listitem>
+        <listitem>
+         <para>
+           Patches should be in-lined (if you can configure your
+           email client to not wrap lines), or attached as plain text
+           attachments so they can be read inline. This may mean some
+           more work for you. However it allows others to review your
+           patch easily and decreases the chances of it being
+           overlooked or forgotten.
+         </para>
+        </listitem>
+        <listitem>
+         <para>
+           Code is usually limited to 80 columns. This helps prevent
+           mailers mangling patches by line wrap. Also it generally
+           makes code easier to read.
+         </para>
+        </listitem>
+        <listitem>
+         <para>
+           If the patch fixes a bug in Bugzilla please provide a link
+           to the bug in the comments of the patch. This will make it
+           easier for the maintainers of Bugzilla.
+         </para>
+        </listitem>
+      </itemizedlist>
+      <sect2 id="Inline-Attachments-with-OE">
+        <title>Inline attachments with Outlook Express</title>
+        <para>
+          Outlook Express is notorious for mangling
+         attachments. Giving the patch a <filename>.txt</filename>
+         extension and attaching will solve the problem for most
+         mailers including Outlook. Also, there is a way to enable
+         Outlook Express send <filename>.diff</filename>
+         attachments.
+        </para>
+        <para>
+          You need following two things to make it work.
+        </para>
+        <orderedlist>
+          <listitem>
+           <para>
+             Make sure that <filename>.diff</filename> files have
+             \r\n line ends, because if OE detects that there is no
+             \r\n line endings it switches to quoted-printable format
+             attachments.
+           </para>
+          </listitem>
+          <listitem>
+           <para>
+             Using regedit add key "Content Type"
+             with value "text/plain" to the
+             <filename>.diff</filename> extension under
+             HKEY_CLASSES_ROOT (same as for <filename>.txt</filename>
+             extension). This tells OE to use
+             Content-Type:&nbsp;text/plain instead of
+             application/octet-stream.
+           </para>
+          </listitem>
+        </orderedlist>
+        <para>
+          Item #1 is important. After you hit "Send" button, go to
+         "Outbox" and using "Properties" verify the message source to
+         make sure that the mail has correct format. You might want
+         to send several test emails to yourself too.
+        </para>
+      </sect2>
+      <sect2 id="Alexandre-Bottom-Line">
+        <title>Alexandre's Bottom Line</title>
+        <para>
+          <quote>The basic rules are: no attachments, no MIME crap, no 
+          line wrapping, a single patch per mail. Basically if I can't 
+          do <command>"cat raw_mail | patch -p0"</command> it's in the
+          wrong format.</quote>
+        </para>
+      </sect2>
+    </sect1>
+
+    <sect1 id="patch-quality">
+      <title>Quality Assurance</title>
+
+      <para>
+        (Or, "How do I get Alexandre to apply my patch quickly so I
+        can build on it and it will not go stale?")
+      </para>
+      <para>
+        Make sure your patch applies to the current CVS head
+        revisions.  If a bunch of patches are committed to CVS that may
+        affect whether your patch will apply cleanly then verify that
+        your patch does apply!   <command>cvs update</command> is your
+        friend!
+      </para>
+      <para>
+        Save yourself some embarrassment and run your patched code
+        against more than just your current test example.  Experience
+        will tell you how much effort to apply here. If there are
+        any conformance tests for the code you're working on, run them
+        and make sure they still pass after your patch is applied. Running
+        tests can be done by running <command>make test</command>. You may
+        need to run <command>make testclean</command> to undo the results
+        of a previous test run. See the <quote>testing</quote> guide for
+        more details on Wine's conformance tests.
+      </para>
+
+    </sect1>
+  <sect1 id="porting">
+    <title>Porting Wine to new Platforms</title>
+    <para>
+      This document provides a few tips on porting Wine to your
+      favorite (UNIX-based) operating system. 
+    </para>
+
+    <sect2>
+      <title>
+       Why <symbol>#ifdef MyOS</symbol> is probably a mistake.
+      </title>
+
+      <para>
+       Operating systems change. Maybe yours doesn't have the
+       <filename>foo.h</filename> header, but maybe a future
+       version will have it. If you want to <symbol>#include
+         &lt;foo.h&gt;</symbol>, it doesn't matter what operating
+       system you are using; it only matters whether
+       <filename>foo.h</filename> is there.
+      </para>
+      <para>
+       Furthermore, operating systems change names or "fork" into
+       several ones. An <symbol>#ifdef MyOs</symbol> will break
+       over time.
+      </para>
+      <para>
+       If you use the feature of <command>autoconf</command> -- the
+       Gnu auto-configuration utility -- wisely, you will help
+       future porters automatically because your changes will test
+       for <emphasis>features</emphasis>, not names of operating
+       systems. A feature can be many things:
+      </para>
+
+      <itemizedlist>
+       <listitem>
+         <para>
+           existence of a header file
+         </para>
+       </listitem>
+       <listitem>
+         <para>
+           existence of a library function
+         </para>
+       </listitem>
+       <listitem>
+         <para>
+           existence of libraries
+         </para>
+       </listitem>
+       <listitem>
+         <para>
+           bugs in header files, library functions, the compiler, ...
+         </para>
+       </listitem>
+      </itemizedlist>
+      <para>
+       You will need Gnu Autoconf, which you can get from your
+       friendly Gnu mirror. This program takes Wine's
+       <filename>configure.ac</filename> file and produces a
+       <filename>configure</filename> shell script that users use
+       to configure Wine to their system.
+      </para>
+      <para>
+       There <emphasis>are</emphasis> exceptions to the "avoid
+       <symbol>#ifdef MyOS</symbol>" rule. Wine, for example, needs
+       the internals of the signal stack -- that cannot easily be
+       described in terms of features. Moreover, you 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>
+
+  <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:
+-->
diff --git a/documentation/winedev-graphical.sgml b/documentation/winedev-graphical.sgml
new file mode 100644 (file)
index 0000000..72c3a04
--- /dev/null
@@ -0,0 +1,40 @@
+  <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:
+-->
diff --git a/documentation/winedev-kernel.sgml b/documentation/winedev-kernel.sgml
new file mode 100644 (file)
index 0000000..700835f
--- /dev/null
@@ -0,0 +1,823 @@
+  <chapter>
+    <title>Kernel modules</title>
+    <para>
+      This section cover the kernel modules. As already stated, Wine
+      implements the NT architecture, hence provides NTDLL for the
+      core kernel functions, and KERNEL32, which is the
+      implementation of the basis of the Win32 subsystem, on top of
+      NTDLL.
+    </para>
+    <sect1 id="ntdll">
+      <title>NTDLL</title>
+      <para>
+       NTDLL provides most of the services you'd expect from a
+       kernel.
+      </para>
+      <para>
+       Process and thread management are part of them (even if
+       process management is still mainly done in KERNEL32, unlike
+       NT). A Windows process runs as a Unix process, and a Windows
+       thread runs as a Unix thread.
+      </para>
+      <para>
+       Wine also provide fibers (which is the Windows name of
+       co-routines).
+      </para>
+      <para>
+       Most of the Windows memory handling (Heap, Global and Local
+       functions, virtual memory...) are easily mapped upon their
+       Unix equivalents. Note the NTDLL doesn't know about 16 bit
+       memory, which is only handled in KERNEL32/KRNL386.EXE (and
+       also the DOS routines).
+      </para>
+      
+      <sect2>
+       <title>File management</title>
+       <para>
+         Wine uses some configuration in order to map Windows
+         filenames (either defined with drive letters, or as UNC
+         names) to the unix filenames. Wine also uses some
+         incantation so that most of file related APIs can also
+         take full unix names. This is handy when passing filenames
+         on the command line.
+       </para>
+       <para>
+         File handles can be waitable objects, as Windows define
+         them.
+       </para>
+       <para>
+         Asynchronous I/O is implemented on file handles by
+         queueing pseudo APC. They are not real APC in the sense
+         that they have the same priority as the threads in the
+         considered process (while APCs on NT have normally a
+         higher priority). These APCs get called when invoking
+         Wine server (which should lead to correct behavior when the
+         program ends up waiting on some object - waiting always
+         implies calling Wine server).
+       </para>
+       <para>
+         FIXME: this should be enhanced and updated to latest work
+         on FS.
+       </para>
+      </sect2>
+
+      <sect2>
+       <title>Synchronization</title>
+       <para>
+         Most of the synchronization (between threads or processes)
+         is done in Wine server, which handles both the waiting
+         operation (on a single object or a set of objects) and the
+         signaling of objects. 
+       </para>
+      </sect2>
+
+      <sect2>
+       <title>Module (DLL) loading</title>
+       <para>
+         Wine is able to load any NE and PE module. In all cases,
+         the module's binary code is directly executed by the
+         processor.
+       </para>
+      </sect2>
+
+      <sect2>
+       <title>Device management</title>
+       <para>
+         Wine allows usage a wide variety of devices:
+         <itemizedlist>
+           <listitem>
+             <para>
+               Communication ports are mapped to Unix
+               communication ports (if they have sufficient
+               permissions).
+             </para>
+           </listitem>
+           <listitem>
+             <para>
+               Parallel ports are mapped to Unix parallel ports (if
+               they have sufficient permissions).
+             </para>
+           </listitem>
+           <listitem>
+             <para>
+               CDROM: the Windows device I/O control calls are
+               mapped onto Unix <function>ioctl()</function>.
+             </para>
+           </listitem>
+           <listitem>
+             <para>
+               Some Win9x VxDs are supported, by rewriting some of
+               their internal behavior. But this support is
+               limited. Portable programs to Windows NT shouldn't
+               need them.
+             </para>
+             <para>
+               Wine will not support native VxD.
+             </para>
+           </listitem>
+         </itemizedlist>
+       </para>
+      </sect2>
+      <sect2 id="threading">
+       <title>Multi-threading in Wine</title>
+
+       <para>
+         This section will assume you understand the basics of
+         multithreading. If not there are plenty of good tutorials
+         available on the net to get you started.
+       </para>
+
+       <para>
+         Threading in Wine is somewhat complex due to several
+         factors. The first is the advanced level of multithreading
+         support provided by Windows - there are far more threading
+         related constructs available in Win32 than the Linux
+         equivalent (pthreads). The second is the need to be able to
+         map Win32 threads to native Linux threads which provides us
+         with benefits like having the kernel schedule them without
+         our intervention. While it's possible to implement threading
+         entirely without kernel support, doing so is not desirable
+         on most platforms that Wine runs on.
+       </para>
+
+       <sect3>
+         <title> Threading support in Win32 </title>
+
+         <para>
+           Win32 is an unusually thread friendly API. Not only is it
+           entirely thread safe, but it provides many different
+           facilities for working with threads. These range from the
+           basics such as starting and stopping threads, to the
+           extremely complex such as injecting threads into other
+           processes and COM inter-thread marshalling.
+         </para>
+
+         <para>
+           One of the primary challenges of writing Wine code
+           therefore is ensuring that all our DLLs are thread safe,
+           free of race conditions and so on. This isn't simple -
+           don't be afraid to ask if you aren't sure whether a piece
+           of code is thread safe or not!
+         </para>
+
+         <para>
+           Win32 provides many different ways you can make your code
+           thread safe however the most common are <emphasis>critical
+             section</emphasis> and the <emphasis>interlocked
+             functions</emphasis>. Critical sections are a type of
+           mutex designed to protect a geographic area of code. If
+           you don't want multiple threads running in a piece of code
+           at once, you can protect them with calls to
+           <function>EnterCriticalSection</function> and
+           <function>LeaveCriticalSection</function>. The first call
+           to <function>EnterCriticalSection</function> by a thread
+           will lock the section and continue without stopping. If
+           another thread calls it then it will block until the
+           original thread calls
+           <function>LeaveCriticalSection</function> again.
+         </para>
+
+         <para>
+           It is therefore vitally important that if you use critical
+           sections to make some code thread-safe, that you check
+           every possible codepath out of the code to ensure that any
+           held sections are left. Code like this:
+         </para>
+
+         <programlisting>
+if (res != ERROR_SUCCESS) return res;
+         </programlisting>
+
+         <para>
+           is extremely suspect in a function that also contains a
+           call to <function>EnterCriticalSection</function>. Be
+           careful.
+         </para>
+
+         <para>
+           If a thread blocks while waiting for another thread to
+           leave a critical section, you will see an error from the
+           <function>RtlpWaitForCriticalSection</function> function,
+           along with a note of which thread is holding the
+           lock. This only appears after a certain timeout, normally
+           a few seconds. It's possible the thread holding the lock
+           is just being really slow which is why Wine won't
+           terminate the app like a non-checked build of Windows
+           would, but the most common cause is that for some reason a
+           thread forgot to call
+           <function>LeaveCriticalSection</function>, or died while
+           holding the lock (perhaps because it was in turn waiting
+           for another lock). This doesn't just happen in Wine code:
+           a deadlock while waiting for a critical section could be
+           due to a bug in the app triggered by a slight difference
+           in the emulation.
+         </para>
+    
+         <para>
+           Another popular mechanism available is the use of
+           functions like <function>InterlockedIncrement</function>
+           and <function>InterlockedExchange</function>. These make
+           use of native CPU abilities to execute a single
+           instruction while ensuring any other processors on the
+           system cannot access memory, and allow you to do common
+           operations like add/remove/check a variable in thread-safe
+           code without holding a mutex. These are useful for
+           reference counting especially in free-threaded (thread
+           safe) COM objects.
+         </para>
+
+         <para>
+           Finally, the usage of TLS slots are also popular. TLS
+           stands for thread-local storage, and is a set of slots
+           scoped local to a thread which you can store pointers
+           in. Look on MSDN for the <function>TlsAlloc</function>
+           function to learn more about the Win32 implementation of
+           this. Essentially, the contents of a given slot will be
+           different in each thread, so you can use this to store
+           data that is only meaningful in the context of a single
+           thread. On recent versions of Linux the __thread keyword
+           provides a convenient interface to this functionality - a
+           more portable API is exposed in the pthread
+           library. However, these facilities is not used by Wine,
+           rather, we implement Win32 TLS entirely ourselves.
+         </para>
+       </sect3>
+
+       <sect3>
+         <title> SysLevels </title>
+
+         <para>
+           SysLevels are an undocumented Windows-internal
+           thread-safety system. They are basically critical sections
+           which must be taken in a particular order. The mechanism
+           is generic but there are always three syslevels: level 1
+           is the Win16 mutex, level 2 is the USER mutex and level 3
+           is the GDI mutex.
+         </para>
+
+         <para>
+           When entering a syslevel, the code (in
+           <filename>dlls/kernel/syslevel.c</filename>) will check
+           that a higher syslevel is not already held and produce an
+           error if so. This is because it's not legal to enter level
+           2 while holding level 3 - first, you must leave level 3.
+         </para>
+
+         <para>
+           Throughout the code you may see calls to
+           <function>_ConfirmSysLevel()</function> and
+           <function>_CheckNotSysLevel()</function>. These functions
+           are essentially assertions about the syslevel states and
+           can be used to check that the rules have not been
+           accidentally violated. In particular,
+           <function>_CheckNotSysLevel()</function> will break
+           (probably into the debugger) if the check fails. If this
+           happens the solution is to get a backtrace and find out,
+           by reading the source of the wine functions called along
+           the way, how Wine got into the invalid state.
+         </para>
+    
+       </sect3>
+
+       <sect3>
+         <title> POSIX threading vs kernel threading </title>
+
+         <para>
+           Wine runs in one of two modes: either pthreads (posix
+           threading) or kthreads (kernel threading). This section
+           explains the differences between them. The one that is
+           used is automatically selected on startup by a small test
+           program which then execs the correct binary, either
+           wine-kthread or wine-pthread. On NPTL-enabled systems
+           pthreads will be used, and on older non-NPTL systems
+           kthreads is selected.
+         </para>
+
+         <para>
+           Let's start with a bit of history. Back in the dark ages
+           when Wines threading support was first implemented a
+           problem was faced - Windows had much more capable
+           threading APIs than Linux did. This presented a problem -
+           Wine works either by reimplementing an API entirely or by
+           mapping it onto the underlying systems equivalent. How
+           could Win32 threading be implemented using a library which
+           did not have all the neeed features? The answer, of
+           course, was that it couldn't be.
+         </para>
+
+         <para>
+           On Linux the pthreads interface is used to start, stop and
+           control threads. The pthreads library in turn is based on
+           top of so-called "kernel threads" which are created using
+           the <function>clone(2)</function> syscall. Pthreads
+           provides a nicer (more portable) interface to this
+           functionality and also provides APIs for controlling
+           mutexes. There is a <ulink 
+           url="http://www.llnl.gov/computing/tutorials/pthreads/">
+           good tutorial on pthreads </ulink> available if you want
+           to learn more.
+         </para>
+
+         <para>
+           As pthreads did not provide the necessary semantics to
+           implement Win32 threading, the decision was made to
+           implement Win32 threading on top of the underlying kernel
+           threads by using syscalls like <function>clone</function>
+           directly. This provided maximum flexibility and allowed a
+           correct implementation but caused some bad side
+           effects. Most notably, all the userland Linux APIs assumed
+           that the user was utilising the pthreads library. Some
+           only enabled thread safety when they detected that
+           pthreads was in use - this is true of glibc, for
+           instance. Worse, pthreads and pure kernel threads had
+           strange interactions when run in the same process yet some
+           libraries used by Wine used pthreads internally. Throw in
+           source code porting using WineLib - where you have both
+           UNIX and Win32 code in the same process - and chaos was
+           the result.
+         </para>
+
+         <para>
+           The solution was simple yet ingenius: Wine would provide
+           its own implementation of the pthread library
+           <emphasis>inside</emphasis> its own binary. Due to the
+           semantics of ELF symbol scoping, this would cause Wines
+           own implementations to override any implementation loaded
+           later on (like the real libpthread.so). Therefore, any
+           calls to the pthread APIs in external libraries would be
+           linked to Wines instead of the systems pthreads library,
+           and Wine implemented pthreads by using the standard
+           Windows threading APIs it in turn implemented itself.
+         </para>
+
+         <para>
+           As a result, libraries that only became thread-safe in the
+           presence of a loaded pthreads implementation would now do
+           so, and any external code that used pthreads would
+           actually end up creating Win32 threads that Wine was aware
+           of and controlled. This worked quite nicely for a long
+           time, even though it required doing some extremely
+           un-kosher things like overriding internal libc structures
+           and functions. That is, it worked until NPTL was developed
+           at which point the underlying thread implementation on
+           Linux changed dramatically.
+         </para>
+
+         <para>
+           The fake pthread implementation can be found in
+           <filename>loader/kthread.c</filename>, which is used to
+           produce to wine-kthread binary. In contrast,
+           loader/pthread.c produces the wine-pthread binary which is
+           used on newer NPTL systems.
+         </para>
+
+         <para>
+           NPTL is a new threading subsystem for Linux that hugely
+           improves its performance and flexibility. By allowing
+           threads to become much more scalable and adding new
+           pthread APIs, NPTL made Linux competitive with Windows in
+           the multi-threaded world. Unfortunately it also broke many
+           assumptions made by Wine (as well as other applications
+           such as the Sun JVM and RealPlayer) in the process.
+         </para>
+
+         <para>
+           There was, however, some good news. NPTL made Linux
+           threading powerful enough that Win32 threads could now be
+           implemented on top of pthreads like any other normal
+           application. There would no longer be problems with mixing
+           win32-kthreads and pthreads created by external libraries,
+           and no need to override glibc internals. As you can see
+           from the relative sizes of the
+           <filename>loader/kthread.c</filename> and
+           <filename>loader/pthread.c</filename> files, the
+           difference in code complexity is considerable. NPTL also
+           made several other semantic changes to things such as
+           signal delivery so changes were required in many different
+           places in Wine.
+         </para>
+
+         <para>
+           On non-Linux systems the threading interface is typically
+           not powerful enough to replicate the semantics Win32
+           applications expect and so kthreads with the pthread
+           overrides are used.
+         </para>
+       </sect3>
+
+       <sect3>
+         <title> The Win32 thread environment </title>
+
+         <para>
+           All Win32 code, whether from a native EXE/DLL or in Wine 
+           itself, expects certain constructs to be present in its
+           environment. This section explores what those constructs
+           are and how Wine sets them up. The lack of this
+           environment is one thing that makes it hard to use Wine
+           code directly from standard Linux applications - in order
+           to interact with Win32 code a thread must first be
+           "adopted" by Wine.
+         </para>
+
+         <para>
+           The first thing Win32 code requires is the
+           <emphasis>TEB</emphasis> or "Thread Environment
+           Block". This is an internal (undocumented) Windows
+           structure associated with every thread which stores a
+           variety of things such as TLS slots, a pointer to the
+           threads message queue, the last error code and so on. You
+           can see the definition of the TEB in
+           <filename>include/thread.h</filename>, or at least what we
+           know of it so far. Being internal and subject to change,
+           the layout of the TEB has had to be reverse engineered
+           from scratch.
+         </para>
+
+         <para>
+           A pointer to the TEB is stored in the %fs register and can
+           be accessed using <function>NtCurrentTeb()</function> from
+           within Wine code. %fs actually stores a selector, and
+           setting it therefore requires modifying the processes
+           local descriptor table (LDT) - the code to do this is in
+           <filename>lib/wine/ldt.c</filename>. 
+         </para>
+
+         <para>
+           The TEB is required by nearly all Win32 code run in the
+           Wine environment, as any wineserver RPC will use it, which
+           in turn implies that any code which could possibly block
+           (for instance by using a critical section) needs it. The
+           TEB also holds the SEH exception handler chain as the
+           first element, so if when disassembling you see code like
+           this:
+         </para>
+
+         <programlisting> movl %esp, %fs:0 </programlisting>
+
+         <para>
+           ... then you are seeing the program set up an SEH handler
+           frame. All threads must have at least one SEH entry, which
+           normally points to the backstop handler which is
+           ultimately responsible for popping up the all-too-familiar
+           "This program has performed an illegal operation and will
+           be terminated" message. On Wine we just drop straight into
+           the debugger. A full description of SEH is out of the
+           scope of this section, however there are some good
+           articles in MSJ if you are interested.
+         </para>
+
+         <para>
+           All Win32-aware threads must have a wineserver
+           connection. Many different APIs require the ability to
+           communicate with the wineserver. In turn, the wineserver
+           must be aware of Win32 threads in order to be able to
+           accurately report information to other parts of the program
+           and do things like route inter-thread messages, dispatch
+           APCs (asynchronous procedure calls) and so on. Therefore a
+           part of thread initialization is initializing the thread
+           serverside. The result is not only correct information in
+           the server, but a set of file descriptors the thread can use
+           to communicate with the server - the request fd, reply fd
+           and wait fd (used for blocking).
+         </para>
+       </sect3>
+      </sect2>
+    </sect1>
+
+    <sect1>
+      <title>KERNEL Module</title>
+      
+      <para>
+       FIXME: Needs some content...
+      </para>
+      <sect2 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>
+      </sect2>
+    </sect1>
+    
+    <sect1 id="initialization">
+
+      <title> The Wine initialization process </title>
+
+      <para>
+       Wine has a rather complex startup procedure, so unlike many
+       programs the best place to begin exploring the code-base is
+       <emphasis>not</emphasis> in fact at the
+       <function>main()</function> function but instead at some of the
+       more straightforward DLLs that exist on the periphery such as
+       MSI, the widget library (in USER and COMCTL32) etc. The purpose
+       of this section is to document and explain how Wine starts up
+       from the moment the user runs "wine myprogram.exe" to the point
+       at which myprogram gets control.
+      </para>
+
+      <sect2>
+       <title> First Steps </title>
+
+       <para>
+         The actual wine binary that the user runs does not do very much, in fact it is only
+         responsible for checking the threading model in use (NPTL vs LinuxThreads) and then invoking
+         a new binary which performs the next stage in the startup sequence. See the threading chapter
+         for more information on this check and why it's necessary. You can find this code in
+         <filename>loader/glibc.c</filename>. The result of this check is an exec of either
+         wine-pthread or wine-kthread, potentially (on Linux) via
+         the <emphasis>preloader</emphasis>. We need to use separate binaries here because overriding
+         the native pthreads library requires us to exploit a property of ELF symbol fixup semantics:
+         it's not possible to do this without starting a new process.
+       </para>
+
+       <para>
+         The Wine preloader is found in <filename>loader/preloader.c</filename>, and is required in
+         order to impose a Win32 style address space layout upon the newly created Win32 process. The
+         details of what this does is covered in the address space layout chapter. The preloader is a
+         statically linked ELF binary which is passed the name of the actual Wine binary to run (either
+         wine-kthread or wine-pthread) along with the arguments the user passed in from the command
+         line. The preloader is an unusual program: it does not have a main() function. In standard ELF
+         applications, the entry point is actually at a symbol named _start: this is provided by the
+         standard gcc infrastructure and normally jumps to <function>__libc_start_main</function> which
+         initializes glibc before passing control to the main function as defined by the programmer.
+       </para>
+
+       <para>
+         The preloader takes control direct from the entry point for a few reasons. Firstly, it is
+         required that glibc is not initialized twice: the result of such behaviour is undefined and
+         subject to change without notice. Secondly, it's possible that as part of initializing glibc,
+         the address space layout could be changed - for instance, any call to malloc will initialize a
+         heap arena which modifies the VM mappings. Finally, glibc does not return to _start at any
+         point, so by reusing it we avoid the need to recreate the ELF bootstrap stack (env, argv,
+         auxiliary array etc).
+       </para>
+
+       <para>
+         The preloader is responsible for two things: protecting important regions of the address
+         space so the dynamic linker does not map shared libraries into them, and once that is done
+         loading the real Wine binary off disk, linking it and starting it up. Normally all this is
+         done automatically by glibc and the kernel but as we intercepted this process by using a
+         static binary it's up to us to restart the process. The bulk of the code in the preloader is
+         about loading wine-[pk]thread and ld-linux.so.2 off disk, linking them together, then
+         starting the dynamic linking process.
+       </para>
+
+       <para>
+         One of the last things the preloader does before jumping into the dynamic linker is scan the
+         symbol table of the loaded Wine binary and set the value of a global variable directly: this
+         is a more efficient way of passing information to the main Wine program than flattening the
+         data structures into an environment variable or command line parameter then unpacking it on
+         the other side, but it achieves pretty much the same thing. The global variable set points to
+         the preload descriptor table, which contains the VMA regions protected by the preloader. This
+         allows Wine to unmap them once the dynamic linker has been run, so leaving gaps we can
+         initialize properly later on.
+       </para>
+
+      </sect2>
+    
+      <sect2>
+       <title> Starting the emulator </title>
+
+       <para>
+         The process of starting up the emulator itself is mostly one of chaining through various
+         initializer functions defined in the core libraries and DLLs: libwine, then NTDLL, then kernel32.
+       </para>
+
+       <para>
+         Both the wine-pthread and wine-kthread binaries share a common <function>main</function>
+         function, defined in <filename>loader/main.c</filename>, so no matter which binary is selected
+         after the preloader has run we start here. This passes the information provided by the
+         preloader into libwine and then calls wine_init, defined
+         in <filename>libs/wine/loader.c</filename>. This is where the emulation really starts:
+         <function>wine_init</function> can, with the correct preparation,
+         be called from programs other than the wine loader itself.
+       </para>
+
+       <para>
+         <function>wine_init</function> does some very basic setup tasks such as initializing the
+         debugging infrastructure, yet more address space manipulation (see the information on the
+         4G/4G VM split in the address space chapter), before loading NTDLL - the core of both Wine and
+         the Windows NT series - and jumping to the <function>__wine_process_init</function> function defined
+         in <filename>dlls/ntdll/loader.c</filename>
+       </para>
+
+       <para>
+         This function is responsible for initializing the primary Win32 environment. In thread_init(),
+         it sets up the TEB, the wineserver connection for the main thread and the process heap. See
+         the threading chapter for more information on this.
+       </para>
+
+       <para>
+         Finally, it loads and jumps to <function>__wine_kernel_init</function> in kernel32.dll: this
+         is defined in <filename>dlls/kernel32/process.c</filename>. This is where the bulk of the work
+         is done. The kernel32 initialization code retrieves the startup info for the process from the
+         server, initializes the registry, sets up the drive mapping system and locale data, then
+         begins loading the requested application itself. Each process has a STARTUPINFO block that can
+         be passed into <function>CreateProcess</function> specifying various things like how the first
+         window should be displayed: this is sent to the new process via the wineserver.
+       </para>
+
+       <para>
+         After determining the type of file given to Wine by the user (a Win32 EXE file, a Win16 EXE, a
+         Winelib app etc), the program is loaded into memory (which may involve loading and
+         initializing other DLLs, the bulk of Wines startup code), before control reaches the end of
+         <function>__wine_kernel_init</function>. This function ends with the new process stack being
+         initialized, and start_process being called on the new stack. Nearly there!
+       </para>
+
+       <para>
+         The final element of initializing Wine is starting the newly loaded program
+         itself. <function>start_process</function> sets up the SEH backstop handler, calls
+         <function>LdrInitializeThunk</function> which performs the last part of the process
+         initialization (such as performing relocations and calling the DllMains with PROCESS_ATTACH),
+         grabs the entry point of the executable and then on this line:
+       </para>
+
+       <programlisting>
+ExitProcess( entry( peb ) );
+       </programlisting>
+
+       <para>
+         ... jumps to the entry point of the program. At this point the users program is running and
+         the API provided by Wine is ready to be used. When entry returns,
+         the <function>ExitProcess</function> API will be used to initialize a graceful shutdown.
+       </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:
+-->
diff --git a/documentation/winedev-otherdebug.sgml b/documentation/winedev-otherdebug.sgml
new file mode 100644 (file)
index 0000000..da501c4
--- /dev/null
@@ -0,0 +1,508 @@
+  <chapter id="otherdebug">
+    <title>Other debugging techniques</title>
+    <sect1 id="hardware-trace">
+      <title>Doing A Hardware Trace</title>
+
+      <para>
+        The primary reason to do this is to reverse engineer a
+        hardware device for which you don't have documentation, but
+        can get to work under Wine.
+      </para>
+      <para>
+        This lot is aimed at parallel port devices, and in particular
+        parallel port scanners which are now so cheap they are
+        virtually being given away. The problem is that few
+        manufactures will release any programming information which
+        prevents drivers being written for Sane, and the traditional
+        technique of using DOSemu to produce the traces does not work
+        as the scanners invariably only have drivers for Windows.
+      </para>
+      <para>
+        Presuming that you have compiled and installed wine the first
+        thing to do is is to enable direct hardware access to your
+        parallel port. To do this edit <filename>config</filename>
+        (usually in <filename>~/.wine/</filename>) and in the
+        ports section add the following two lines
+      </para>
+      <programlisting>
+read=0x378,0x379,0x37a,0x37c,0x77a
+write=0x378,x379,0x37a,0x37c,0x77a
+      </programlisting>
+      <para>
+        This adds the necessary access required for SPP/PS2/EPP/ECP
+        parallel port on LPT1. You will need to adjust these number
+        accordingly if your parallel port is on LPT2 or LPT0.
+      </para>
+      <para>
+        When starting wine use the following command line, where
+        <literal>XXXX</literal> is the program you need to run in
+        order to access your scanner, and <literal>YYYY</literal> is
+        the file your trace will be stored in:
+      </para>
+      <programlisting>
+WINEDEBUG=+io wine XXXX 2&gt; &gt;(sed 's/^[^:]*:io:[^ ]* //' &gt; YYYY)
+      </programlisting>
+      <para>
+        You will need large amounts of hard disk space (read hundreds
+        of megabytes if you do a full page scan), and for reasonable
+        performance a really fast processor and lots of RAM.
+      </para>
+      <para>
+       You will need to postprocess the output into a more manageable
+       format, using the <command>shrink</command> program. First
+        you need to compile the source (which is located at the end of
+       this section):
+      <programlisting>
+cc shrink.c -o shrink
+      </programlisting>
+      </para>
+      <para>
+        Use the <command>shrink</command> program to reduce the
+        physical size of the raw log as follows:
+      </para>
+      <programlisting>
+cat log | shrink &gt; log2
+      </programlisting>
+      <para>
+        The trace has the basic form of
+      </para>
+      <programlisting>
+XXXX &gt; YY @ ZZZZ:ZZZZ
+      </programlisting>
+      <para>
+        where <literal>XXXX</literal> is the port in hexadecimal being
+        accessed, <literal>YY</literal> is the data written (or read)
+        from the port, and <literal>ZZZZ:ZZZZ</literal> is the address
+        in memory of the instruction that accessed the port. The
+        direction of the arrow indicates whether the data was written
+        or read from the port.
+      </para>
+      <programlisting>
+&gt; data was written to the port
+&lt; data was read from the port
+      </programlisting>
+      <para>
+        My basic tip for interpreting these logs is to pay close
+        attention to the addresses of the IO instructions. Their
+        grouping and sometimes proximity should reveal the presence of
+        subroutines in the driver. By studying the different versions
+        you should be able to work them out. For example consider the
+        following section of trace from my UMAX Astra 600P
+      </para>
+      <programlisting>
+0x378 &gt; 55 @ 0297:01ec
+0x37a &gt; 05 @ 0297:01f5
+0x379 &lt; 8f @ 0297:01fa
+0x37a &gt; 04 @ 0297:0211
+0x378 &gt; aa @ 0297:01ec
+0x37a &gt; 05 @ 0297:01f5
+0x379 &lt; 8f @ 0297:01fa
+0x37a &gt; 04 @ 0297:0211
+0x378 &gt; 00 @ 0297:01ec
+0x37a &gt; 05 @ 0297:01f5
+0x379 &lt; 8f @ 0297:01fa
+0x37a &gt; 04 @ 0297:0211
+0x378 &gt; 00 @ 0297:01ec
+0x37a &gt; 05 @ 0297:01f5
+0x379 &lt; 8f @ 0297:01fa
+0x37a &gt; 04 @ 0297:0211
+0x378 &gt; 00 @ 0297:01ec
+0x37a &gt; 05 @ 0297:01f5
+0x379 &lt; 8f @ 0297:01fa
+0x37a &gt; 04 @ 0297:0211
+0x378 &gt; 00 @ 0297:01ec
+0x37a &gt; 05 @ 0297:01f5
+0x379 &lt; 8f @ 0297:01fa
+0x37a &gt; 04 @ 0297:0211
+      </programlisting>
+      <para>
+        As you can see there is a repeating structure starting at
+        address <literal>0297:01ec</literal> that consists of four io
+        accesses on the parallel port. Looking at it the first io
+        access writes a changing byte to the data port the second
+        always writes the byte <literal>0x05</literal> to the control
+        port, then a value which always seems to
+        <literal>0x8f</literal> is read from the status port at which
+        point a byte <literal>0x04</literal> is written to the control
+        port. By studying this and other sections of the trace we can
+        write a C routine that emulates this, shown below with some
+        macros to make reading/writing on the parallel port easier to
+        read.
+      </para>
+      <programlisting>
+#define r_dtr(x)        inb(x)
+#define r_str(x)        inb(x+1)
+#define r_ctr(x)        inb(x+2)
+#define w_dtr(x,y)      outb(y, x)
+#define w_str(x,y)      outb(y, x+1)
+#define w_ctr(x,y)      outb(y, x+2)
+
+/* Seems to be sending a command byte to the scanner */
+int udpp_put(int udpp_base, unsigned char command)
+{
+    int loop, value;
+
+    w_dtr(udpp_base, command);
+    w_ctr(udpp_base, 0x05);
+
+    for (loop=0; loop &lt; 10; loop++)
+        if ((value = r_str(udpp_base)) & 0x80) 
+       {
+            w_ctr(udpp_base, 0x04);
+            return value & 0xf8;
+        }
+
+    return (value & 0xf8) | 0x01;
+}
+      </programlisting>
+      <para>
+        For the UMAX Astra 600P only seven such routines exist (well
+        14 really, seven for SPP and seven for EPP). Whether you
+        choose to disassemble the driver at this point to verify the
+        routines is your own choice. If you do, the address from the
+        trace should help in locating them in the disassembly.
+      </para>
+      <para>
+        You will probably then find it useful to write a script/perl/C
+        program to analyse the logfile and decode them futher as this
+        can reveal higher level grouping of the low level routines.
+        For example from the logs from my UMAX Astra 600P when decoded
+        further reveal (this is a small snippet)
+      </para>
+      <programlisting>
+start:
+put: 55 8f
+put: aa 8f
+put: 00 8f
+put: 00 8f
+put: 00 8f
+put: c2 8f
+wait: ff
+get: af,87
+wait: ff
+get: af,87
+end: cc
+start:
+put: 55 8f
+put: aa 8f
+put: 00 8f
+put: 03 8f
+put: 05 8f
+put: 84 8f
+wait: ff
+      </programlisting>
+      <para>
+        From this it is easy to see that <varname>put</varname>
+        routine is often grouped together in five successive calls
+        sending information to the scanner. Once these are understood
+        it should be possible to process the logs further to show the
+        higher level routines in an easy to see format. Once the
+        highest level format that you can derive from this process is
+        understood, you then need to produce a series of scans varying
+        only one parameter between them, so you can discover how to
+        set the various parameters for the scanner.
+      </para>
+
+      <para>
+        The following is the <filename>shrink.c</filename> program:
+      <programlisting>
+/* Copyright David Campbell &lt;campbell@torque.net&gt; */
+#include &lt;stdio.h&gt;
+#include &lt;string.h&gt;
+
+int main (void)
+{
+    char buff[256], lastline[256] = "";
+    int count = 0;
+
+    while (!feof (stdin))
+    {
+        fgets (buff, sizeof (buff), stdin);
+        if (strcmp (buff, lastline))
+       {
+           if (count &gt; 1)
+               printf ("# Last line repeated %i times #\n", count);
+           printf ("%s", buff);
+           strcpy (lastline, buff);
+           count = 1;
+       }
+        else count++;
+    }
+    return 0;
+}
+      </programlisting>
+      </para>
+    </sect1>
+
+    <sect1 id="undoc-func">
+      <title>Understanding undocumented APIs</title>
+
+      <para>
+       Some background:  On the i386 class of machines, stack entries are
+       usually dword (4 bytes) in size, little-endian. The stack grows
+       downward in memory. The stack pointer, maintained in the 
+       <literal>esp</literal> register, points to the last valid entry; 
+       thus, the operation of pushing a value onto the stack involves 
+       decrementing <literal>esp</literal> and then moving the value into 
+       the memory pointed to by <literal>esp</literal>
+       (i.e., <literal>push p</literal> in assembly resembles 
+       <literal>*(--esp) = p;</literal> in C). Removing (popping)
+       values off the stack is the reverse (i.e., <literal>pop p</literal> 
+       corresponds to <literal>p = *(esp++);</literal> in C).
+      </para>
+
+      <para>
+       In the <literal>stdcall</literal> calling convention, arguments are 
+       pushed onto the stack right-to-left. For example, the C call
+       <function>myfunction(40, 20, 70, 30);</function> is expressed in 
+       Intel assembly as:
+       <screen>
+    push 30
+    push 70
+    push 20
+    push 40
+    call myfunction
+       </screen>
+       The called function is responsible for removing the arguments 
+       off the stack. Thus, before the call to myfunction, the
+       stack would look like:
+       <screen>
+             [local variable or temporary]
+             [local variable or temporary]
+              30
+              70
+              20
+    esp ->    40
+       </screen>
+       After the call returns, it should look like:
+       <screen>
+             [local variable or temporary]
+    esp ->   [local variable or temporary]
+       </screen>
+      </para>
+
+      <para>
+       To restore the stack to this state, the called function must know how
+       many arguments to remove (which is the number of arguments it takes).
+       This is a problem if the function is undocumented.
+      </para>
+
+      <para>
+       One way to attempt to document the number of arguments each function
+       takes is to create a wrapper around that function that detects the
+       stack offset. Essentially, each wrapper assumes that the function will 
+       take a large number of arguments. The wrapper copies each of these 
+       arguments into its stack, calls the actual function, and then calculates 
+       the number of arguments by checking esp before and after the call.
+      </para>
+
+      <para>
+       The main problem with this scheme is that the function must actually
+       be called from another program. Many of these functions are seldom
+       used. An attempt was made to aggressively query each function in a
+       given library (<filename>ntdll.dll</filename>) by passing 64 arguments, 
+       all 0, to each function. Unfortunately, Windows NT quickly goes to a 
+       blue screen of death, even if the program is run from a 
+       non-administrator account.
+      </para>
+
+      <para>
+       Another method that has been much more successful is to attempt to
+       figure out how many arguments each function is removing from the
+       stack. This instruction, <literal>ret hhll</literal> (where 
+       <symbol>hhll</symbol> is the number of bytes to remove, i.e. the 
+       number of arguments times 4), contains the bytes 
+       <literal>0xc2 ll hh</literal> in memory. It is a reasonable
+       assumption that few, if any, functions take more than 16 arguments; 
+       therefore, simply searching for 
+       <literal>hh == 0 && ll &lt; 0x40</literal>  starting from the 
+       address of a function yields the correct number of arguments most 
+       of the time.
+      </para>
+
+      <para>
+       Of course, this is not without errors. <literal>ret 00ll</literal> 
+       is not the only instruction that can have the byte sequence 
+       <literal>0xc2 ll 0x0</literal>; for example, 
+       <literal>push 0x000040c2</literal> has the byte sequence
+       <literal>0x68 0xc2 0x40 0x0 0x0</literal>, which matches 
+       the above. Properly, the utility should look for this sequence 
+       only on an instruction boundary; unfortunately, finding 
+       instruction boundaries on an i386 requires implementing a full 
+       disassembler -- quite a daunting task. Besides, the probability 
+       of having such a byte sequence that is not the actual return 
+       instruction is fairly low.
+      </para>
+
+      <para>
+       Much more troublesome is the non-linear flow of a function. For
+       example, consider the following two functions:
+       <screen>
+    somefunction1:
+        jmp  somefunction1_impl
+
+    somefunction2:
+        ret  0004
+
+    somefunction1_impl:
+        ret  0008
+       </screen>
+       In this case, we would incorrectly detect both 
+       <function>somefunction1</function> and
+       <function>somefunction2</function> as taking only a single 
+       argument, whereas <function>somefunction1</function> really 
+       takes two arguments.
+      </para>
+
+      <para>
+       With these limitations in mind, it is possible to implement
+       more stubs 
+       in Wine and, eventually, the functions themselves.
+      </para>
+    </sect1>
+    <sect1>
+      <title>How to do regression testing using CVS</title>
+
+      <para>
+       A problem that can happen sometimes is 'it used to work
+       before, now it doesn't anymore...'. Here is a step by step
+       procedure to try to pinpoint when the problem occurred. This
+       is <emphasis>NOT</emphasis> for casual users.
+      </para>
+      
+      <orderedlist>
+      <listitem>
+         <para>
+           Get the <quote>full CVS</quote> archive from winehq. This
+           archive is the CVS tree but with the tags controlling the
+           versioning system. It's a big file (> 40 meg) with a name
+           like full-cvs-&lt;last update date> (it's more than 100mb
+           when uncompressed, you can't very well do this with
+           small, old computers or slow Internet connections).
+         </para>
+       </listitem>
+       <listitem>
+         <para>
+           untar it into a repository directory:
+           <screen>
+cd /home/gerard
+tar -zxf full-cvs-2003-08-18.tar.gz
+mv wine repository
+           </screen>
+         </para>
+       </listitem>
+       <listitem>
+         <para>
+           extract a new destination directory. This directory must
+           not be in a subdirectory of the repository else
+           <command>cvs</command> will think it's part of the
+           repository and deny you an extraction in the repository:
+           <screen>
+cd /home/gerard
+mv wine wine_current (-> this protects your current wine sandbox, if any)
+export CVSROOT=/home/gerard/repository
+cvs -d $CVSROOT checkout wine
+           </screen>
+         </para>
+         <para>
+           Note that it's not possible to do a checkout at a given
+           date; you always do the checkout for the last date where
+           the full-cvs-xxx snapshot was generated.
+         </para>
+         <para>
+           Note also that it is possible to do all this with a direct
+           CVS connection, of course. The full CVS file method is less
+           painful for the WineHQ CVS server and probably a bit faster
+           if you don't have a very good net connection.
+         </para>
+       </listitem>
+       <listitem>
+         <para>
+           you will have now in the <filename>~/wine</filename>
+           directory an image of the CVS tree, on the client side.
+           Now update this image to the date you want:
+           <screen>
+cd /home/gerard/wine
+cvs update -PAd -D "2004-08-23 CDT"   
+           </screen>
+         </para>
+         <para>
+           The date format is <literal>YYYY-MM-DD HH:MM:SS</literal>.
+           Using the CST date format ensure that you will be able to
+           extract patches in a way that will be compatible with the
+           wine-cvs archive
+           <ulink url="http://www.winehq.org/hypermail/wine-cvs">
+             http://www.winehq.org/hypermail/wine-cvs</ulink>
+         </para>
+         <para>
+           Many messages will inform you that more recent files have
+           been deleted to set back the client cvs tree to the date
+           you asked, for example:
+           <screen>
+cvs update: tsx11/ts_xf86dga2.c is no longer in the repository
+           </screen>
+         </para>
+         <para>
+           <command>cvs update</command> is not limited to upgrade to
+           a <emphasis>newer</emphasis> version as I have believed for
+           far too long :-(
+         </para>
+       </listitem>
+       <listitem>
+         <para>
+           Now proceed as for a normal update:
+         </para>
+         <screen>
+./configure
+make depend && make
+         </screen>
+         <para>
+           If any non-programmer reads this, the fastest method to
+           get at the point where the problem occurred is to use a
+           binary search, that is, if the problem occurred in 1999,
+           start at mid-year, then is the problem is already here,
+           back to 1st April, if not, to 1st October, and so on.
+         </para>
+         <para>
+           If you have lot of hard disk free space (a full compile
+           currently takes 400 Mb), copy the oldest known working
+           version before updating it, it will save time if you need
+           to go back. (it's better to <command>make
+             distclean</command> before going back in time, so you
+           have to make everything if you don't backup the older
+           version)
+         </para>
+         <para>
+           When you have found the day where the problem happened,
+           continue the search using the wine-cvs archive (sorted by
+           date) and a more precise cvs update including hour,
+           minute, second: 
+           <screen>
+cvs update -PAd -D "2004-08-23 15:17:25 CDT"
+           </screen>
+           This will allow you to find easily the exact patch that
+           did it.
+         </para>
+       </listitem>
+       <listitem>
+         <para>
+           If you find the patch that is the cause of the problem,
+           you have almost won; report about it to
+           <ulink url="http://bugs.winehq.org/">Wine Bugzilla</ulink>
+           or subscribe to wine-devel and post it there. There is a
+           chance that the author will jump in to suggest a fix; or
+           there is always the possibility to look hard at the patch
+           until it is coerced to reveal where is the bug :-) 
+         </para>
+       </listitem>
+      </orderedlist>
+    </sect1>
+
+  </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:
+-->
diff --git a/documentation/winedev-windowing.sgml b/documentation/winedev-windowing.sgml
new file mode 100644 (file)
index 0000000..8d8cccc
--- /dev/null
@@ -0,0 +1,673 @@
+  <chapter>
+    <title>Windowing system</title>
+    <sect1>
+      <title>USER Module</title>
+
+      <para>
+       USER implements windowing and messaging subsystems. It also
+       contains code for common controls and for other
+       miscellaneous  stuff (rectangles, clipboard, WNet, etc).
+       Wine USER code is  located in <filename>windows/</filename>,
+       <filename>controls/</filename>, and
+       <filename>misc/</filename> directories.
+      </para>
+      
+      <sect2>
+       <title>Windowing subsystem</title>
+
+       <para><filename>windows/win.c</filename></para>
+       <para><filename>windows/winpos.c</filename></para>
+       <para>
+         Windows are arranged into parent/child hierarchy with one
+         common ancestor for all windows (desktop window). Each
+         window structure contains a pointer to the immediate
+         ancestor (parent window if <constant>WS_CHILD</constant>
+         style bit is set), a pointer to the sibling (returned by
+         <function>GetWindow(..., GW_NEXT)</function>), a pointer
+         to the owner  window (set only for popup window if it was
+         created with valid  <varname>hwndParent</varname>
+         parameter), and a pointer to the first child window
+         (<function>GetWindow(.., GW_CHILD)</function>). All popup
+         and non-child windows are therefore placed in the first
+         level of this hierarchy and their ancestor link
+         (<varname>wnd-&gt;parent</varname>) points to the desktop
+         window.
+       </para>
+       <screen>
+   Desktop window                      - root window
+    |     \      `-.
+    |      \        `-.
+   popup -&gt; wnd1  -&gt;  wnd2               - top level windows    
+    |       \   `-.      `-.
+    |        \     `-.      `-.
+   child1  child2 -&gt; child3  child4     - child windows
+       </screen>
+       <para>
+         Horizontal arrows denote sibling relationship, vertical
+         lines - ancestor/child. To summarize, all windows with the
+         same immediate ancestor are sibling windows, all windows
+         which do not have desktop as their immediate ancestor are
+         child windows. Popup windows behave as topmost top-level
+         windows unless they are owned. In this case the only
+         requirement is that they must precede their owners in the
+         top-level sibling list (they are not topmost). Child
+         windows are confined to the client area of their parent
+         windows (client area is where window gets to do its own
+         drawing, non-client area consists of caption, menu,
+         borders, intrinsic scrollbars, and
+         minimize/maximize/close/help buttons). 
+       </para>
+       <para>
+         Another fairly important concept is
+         <firstterm>z-order</firstterm>. It is derived from the
+         ancestor/child hierarchy and is used to determine
+         "above/below" relationship. For instance, in the example
+         above, z-order is
+       </para>
+          <screen>
+child1-&gt;popup-&gt;child2-&gt;child3-&gt;wnd1-&gt;child4-&gt;wnd2-&gt;desktop.
+       </screen>
+       <para>
+         Current active window ("foreground window" in Win32) is
+         moved to the front of z-order unless its top-level
+         ancestor owns popup windows.
+       </para>
+       <para>
+         All these issues are dealt with (or supposed to be) in
+         <filename>windows/winpos.c</filename> with
+         <function>SetWindowPos()</function> being the primary
+         interface to the window manager.
+       </para>
+       <para>
+         Wine specifics: in default and managed mode each top-level
+         window gets its own X counterpart with desktop window
+         being basically a fake stub. In desktop mode, however,
+         only desktop window has an X window associated with it.
+         Also, <function>SetWindowPos()</function> should
+         eventually be implemented via
+         <function>Begin/End/DeferWindowPos()</function> calls and
+         not the other way around.
+       </para>
+
+       <sect3>
+         <title>Visible region, clipping region and update region</title>
+         
+         <para><filename>windows/dce.c</filename></para>
+         <para><filename>windows/winpos.c</filename></para>
+         <para><filename>windows/painting.c</filename></para>
+         
+            <screen>
+    ________________________
+   |_________               |  A and B are child windows of C
+   |    A    |______        | 
+   |         |      |       |
+   |---------'      |       |
+   |   |      B     |       |
+   |   |            |       |
+   |   `------------'       |
+   |                   C    |
+   `------------------------'
+         </screen>
+         <para>
+           Visible region determines which part of the window is
+           not obscured by other windows. If a window has the
+           <constant>WS_CLIPCHILDREN</constant> style then all
+           areas below its children are considered invisible.
+           Similarly, if the <constant>WS_CLIPSIBLINGS</constant>
+           bit is in effect then all areas obscured by its siblings
+           are invisible. Child windows are always clipped by the
+           boundaries of their parent windows.
+         </para>
+         <para>
+           B has a <constant>WS_CLIPSIBLINGS</constant> style:
+         </para>
+         <screen>
+   .          ______ 
+   :         |      |
+   |   ,-----'      |
+   |   |      B     | - visible region of B
+   |   |            |
+   :   `------------'
+         </screen>
+         <para>
+           When the program requests a <firstterm>display
+             context</firstterm> (DC) for a window it  can specify
+           an optional clipping region that further restricts the
+           area where the graphics output can appear. This area is
+           calculated as an intersection of the visible region and
+           a clipping region. 
+         </para>
+         <para>
+           Program asked for a DC with a clipping region:
+         </para>
+         <screen>
+          ______
+      ,--|--.   |     .    ,--. 
+   ,--+--'  |   |     :   _:  |
+   |  |   B |   |  =&gt; |  |    | - DC region where the painting will
+   |  |     |   |     |  |    |   be visible
+   `--|-----|---'     :  `----'
+      `-----'
+         </screen>
+         <para>
+           When the window manager detects that some part of the window
+           became visible it adds this area to the update region of this
+           window and then generates <constant>WM_ERASEBKGND</constant> and
+           <constant>WM_PAINT</constant> messages.  In addition,
+           <constant>WM_NCPAINT</constant> message is sent when the
+           uncovered area  intersects a nonclient part of the window.
+           Application must reply to the <constant>WM_PAINT</constant>
+           message by calling the
+           <function>BeginPaint()</function>/<function>EndPaint()</function>
+           pair of functions. <function>BeginPaint()</function> returns a DC
+           that uses accumulated update region as a clipping region. This
+           operation cleans up invalidated area and the window will not
+           receive another <constant>WM_PAINT</constant> until the window
+           manager creates a new update region.
+         </para>
+         <para>
+           A was moved to the left:
+         </para>
+         <screen>
+    ________________________       ...          / C update region
+   |______                  |     :      .___ /
+   | A    |_________        |  =&gt; |   ...|___|..
+   |      |         |       |     |   :  |   |
+   |------'         |       |     |   :  '---' 
+   |   |      B     |       |     |   :      \
+   |   |            |       |     :            \
+   |   `------------'       |                    B update region
+   |                   C    |
+   `------------------------'
+         </screen>
+         <para>
+           Windows maintains a display context cache consisting of
+           entries that include the DC itself, the window to which
+           it belongs, and an optional clipping region (visible
+           region is stored in the DC itself). When an API call
+           changes the state of the window tree, window manager has
+           to go through the DC cache to recalculate visible
+           regions for entries whose windows were involved in the
+           operation. DC entries (DCE) can be either private to the
+           window, or private to the window class, or shared
+           between all windows (Windows 3.1 limits the number of
+           shared DCEs to 5).
+         </para>
+       </sect3>
+      </sect2>
+
+      <sect2>
+       <title>Messaging subsystem</title>
+
+       <para><filename>windows/queue.c</filename></para>
+       <para><filename>windows/message.c</filename></para>
+
+       <para>
+         Each Windows task/thread has its own message queue - this
+         is where it gets messages from. Messages can be:
+         <orderedlist>
+           <listitem>
+             <para>
+               generated on the fly (<constant>WM_PAINT</constant>,
+               <constant>WM_NCPAINT</constant>,
+               <constant>WM_TIMER</constant>)
+             </para>
+           </listitem>
+           <listitem>
+             <para>
+               created by the system (hardware messages)
+             </para>
+           </listitem>
+           <listitem>
+             <para>
+               posted by other tasks/threads (<function>PostMessage</function>)
+             </para>
+           </listitem>
+           <listitem>
+             <para>
+               sent by other tasks/threads (<function>SendMessage</function>)
+             </para>
+           </listitem>
+         </orderedlist>
+       </para>
+       <para>
+         Message priority:
+       </para>
+       <para>
+         First the system looks for sent messages, then for posted
+         messages, then for hardware messages, then it checks if
+         the queue has the "dirty window" bit set, and, finally, it
+         checks for expired timers. See
+         <filename>windows/message.c</filename>.
+       </para>
+       <para>
+         From all these different types of messages, only posted
+         messages go directly into the private message queue.
+         System messages (even in Win95) are first collected in the
+         system message queue and then they either sit there until
+         <function>Get/PeekMessage</function> gets to process them
+         or, as in Win95, if system queue is getting clobbered, a
+         special thread ("raw input thread") assigns them to the
+         private queues. Sent messages are queued separately and
+         the sender sleeps until it gets a reply. Special messages
+         are generated on the fly depending on the window/queue
+         state. If the window update region is not empty, the
+         system sets the <constant>QS_PAINT</constant> bit in the
+         owning queue and eventually this window receives a
+         <constant>WM_PAINT</constant> message
+         (<constant>WM_NCPAINT</constant> too if the update region
+         intersects with the non-client area). A timer event is
+         raised when one of the queue timers expire. Depending on
+         the timer parameters <function>DispatchMessage</function>
+         either calls the callback function or the window
+         procedure. If there are no messages pending the
+         task/thread sleeps until messages appear.
+       </para>
+       <para>
+         There are several tricky moments (open for discussion) - 
+       </para>
+
+       <itemizedlist>
+         <listitem>
+           <para>
+             System message order has to be honored and messages
+             should be processed within correct task/thread
+             context. Therefore when <function>Get/PeekMessage</function> encounters
+             unassigned system message and this message appears not
+             to be for the current task/thread it should either
+             skip it (or get rid of it by moving it into the
+             private message queue of the target task/thread -
+             Win95, AFAIK) and look further or roll back and then
+             yield until this message gets processed when system
+             switches to the correct context (Win16). In the first
+             case we lose correct message ordering, in the second
+             case we have the infamous synchronous system message
+             queue. Here is a post to one of the OS/2 newsgroup I
+             found to be relevant:
+           </para>
+           <blockquote>
+             <attribution>by David Charlap</attribution>
+             <para>
+               " Here's the problem in a nutshell, and there is no
+               good solution. Every possible solution creates a
+               different problem.
+             </para>
+             <para>
+               With a windowing system, events can go to many
+               different windows. Most are sent by applications or
+               by the OS when things relating to that window happen
+               (like repainting, timers, etc.)
+             </para>
+             <para>
+               Mouse input events go to the window you click on
+               (unless some window captures the mouse).
+             </para>
+             <para>
+               So far, no problem.  Whenever an event happens, you
+               put a message on the target window's message queue.
+               Every process has a message queue.  If the process
+               queue fills up, the messages back up onto the system
+               queue.
+             </para>
+             <para>
+               This is the first cause of apps hanging the GUI.  If
+               an app doesn't handle messages and they back up into
+               the system queue, other apps can't get any more
+               messages.  The reason is that the next message in
+               line can't go anywhere, and the system won't skip
+               over it.
+             </para>
+             <para>
+               This can be fixed by making apps have bigger private
+               message queues. The SIQ fix does this.  PMQSIZE does
+               this for systems without the SIQ fix.  Applications
+               can also request large queues on their own.
+             </para>
+             <para>
+               Another source of the problem, however, happens when
+               you include keyboard events.  When you press a key,
+               there's no easy way to know what window the
+               keystroke message should be delivered to.
+             </para>
+             <para>
+               Most windowing systems use a concept known as
+               "focus".  The window with focus gets all incoming
+               keyboard messages.  Focus can be changed from window
+               to window by apps or by users clicking on windows.
+             </para>
+             <para>
+               This is the second source of the problem.  Suppose
+               window A has focus. You click on window B and start
+               typing before the window gets focus. Where should
+               the keystrokes go?  On the one hand, they should go
+               to A until the focus actually changes to B.  On the
+               other hand, you probably want the keystrokes to go
+               to B, since you clicked there first.
+             </para>
+             <para>
+               OS/2's solution is that when a focus-changing event
+               happens (like clicking on a window), OS/2 holds all
+               messages in the system queue until the focus change
+               actually happens.  This way, subsequent keystrokes
+               go to the window you clicked on, even if it takes a
+               while for that window to get focus.
+             </para>
+             <para>
+               The downside is that if the window takes a real long
+               time to get focus (maybe it's not handling events,
+               or maybe the window losing focus isn't handling
+               events), everything backs up in the system queue and
+               the system appears hung.
+             </para>
+             <para>
+               There are a few solutions to this problem.
+             </para>
+             <para>
+               One is to make focus policy asynchronous.  That is,
+               focus changing has absolutely nothing to do with the
+               keyboard.  If you click on a window and start typing
+               before the focus actually changes, the keystrokes go
+               to the first window until focus changes, then they
+               go to the second. This is what X-windows does.
+             </para>
+             <para>
+               Another is what NT does.  When focus changes,
+               keyboard events are held in the system message
+               queue, but other events are allowed through. This is
+               "asynchronous" because the messages in the system
+               queue are delivered to the application queues in a
+               different order from that with which they were
+               posted.  If a bad app won't handle the "lose focus"
+               message, it's of no consequence - the app receiving
+               focus will get its "gain focus" message, and the
+               keystrokes will go to it.
+             </para>
+             <para>
+               The NT solution also takes care of the application
+               queue filling up problem.  Since the system delivers
+               messages asynchronously, messages waiting in the
+               system queue will just sit there and the rest of the
+               messages will be delivered to their apps.
+             </para>
+             <para>
+               The OS/2 SIQ solution is this:  When a
+               focus-changing event happens, in addition to
+               blocking further messages from the application
+               queues, a timer is started.  When the timer goes
+               off, if the focus change has not yet happened, the
+               bad app has its focus taken away and all messages
+               targeted at that window are skipped.  When the bad
+               app finally handles the focus change message, OS/2
+               will detect this and stop skipping its messages.
+             </para>
+             
+             <para>
+               As for the pros and cons:
+             </para>
+             <para>
+               The X-windows solution is probably the easiest.  The
+               problem is that users generally don't like having to
+               wait for the focus to change before they start
+               typing.  On many occasions, you can type and the
+               characters end up in the wrong window because
+               something (usually heavy system load) is preventing
+               the focus change from happening in a timely manner.
+             </para>
+             <para>
+               The NT solution seems pretty nice, but making the
+               system message queue asynchronous can cause similar
+               problems to the X-windows problem. Since messages
+               can be delivered out of order, programs must not
+               assume that two messages posted in a particular
+               order will be delivered in that same order.  This
+               can break legacy apps, but since Win32 always had an
+               asynchronous queue, it is fair to simply tell app
+               designers "don't do that".  It's harder to tell app
+               designers something like that on OS/2 - they'll
+               complain "you changed the rules and our apps are
+               breaking."
+             </para>
+             <para>
+               The OS/2 solution's problem is that nothing happens
+               until you try to change window focus, and then wait
+               for the timeout.  Until then, the bad app is not
+               detected and nothing is done."
+             </para>
+           </blockquote>
+         </listitem>
+
+         <listitem>
+           <para>
+             Intertask/interthread
+             <function>SendMessage</function>. The system has to
+             inform the target queue about the forthcoming message,
+             then it has to carry out the context switch and wait
+             until the result is available.  Win16 stores necessary
+             parameters in the queue structure and then calls
+             <function>DirectedYield()</function> function.
+             However, in Win32 there could be  several messages
+             pending sent by preemptively executing threads, and in
+             this case <function>SendMessage</function> has to
+             build some sort of message queue for sent messages.
+             Another issue is what to do with messages sent to the
+             sender when it is blocked inside its own
+             <function>SendMessage</function>. 
+           </para>
+         </listitem>
+       </itemizedlist>
+      </sect2>
+      <sect2 id="accel-impl">
+       <title>Accelerators</title>
+
+       <para>
+         There are <emphasis>three</emphasis> differently sized
+         accelerator structures exposed to the user: 
+       </para>
+       <orderedlist>
+         <listitem>
+           <para>
+             Accelerators in NE resources.  This is also the internal
+             layout of the global handle <type>HACCEL</type> (16 and
+             32) in Windows 95 and Wine. Exposed to the user as Win16
+             global handles <type>HACCEL16</type> and
+             <type>HACCEL32</type> by the Win16/Win32 API.
+             These are 5 bytes long, with no padding:
+             <programlisting>
+BYTE   fVirt;
+WORD   key;
+WORD   cmd;
+             </programlisting>
+           </para>
+         </listitem>
+         <listitem>
+           <para>
+             Accelerators in PE resources. They are exposed to the
+             user only by direct accessing PE resources. These have a
+             size of 8 bytes: 
+           </para>
+           <programlisting>
+BYTE   fVirt;
+BYTE   pad0;
+WORD   key;
+WORD   cmd;
+WORD   pad1;
+           </programlisting>
+         </listitem>
+         <listitem>
+           <para>
+             Accelerators in the Win32 API.  These are exposed to the 
+             user by the  <function>CopyAcceleratorTable</function>
+             and  <function>CreateAcceleratorTable</function> functions
+             in the Win32 API.
+             These have a size of 6 bytes:
+           </para>
+           <programlisting>
+BYTE   fVirt;
+BYTE   pad0;
+WORD   key;
+WORD   cmd;
+           </programlisting>
+         </listitem>
+       </orderedlist>
+
+       <para>
+         Why two types of accelerators in the Win32 API? We can only
+         guess, but my best bet is that the Win32 resource compiler
+         can/does not handle struct packing. Win32 <type>ACCEL</type>
+         is defined using <function>#pragma(2)</function> for the
+         compiler but without any packing for RC, so it will assume
+         <function>#pragma(4)</function>.
+       </para>
+      </sect2>
+    </sect1>
+    <sect1>
+      <title>X Windows System interface</title>
+      <para></para>
+      <sect2>
+       <title>Keyboard mapping</title>
+       <para>
+         Wine now needs to know about your keyboard layout. This
+         requirement comes from a need from many apps to have the
+         correct scancodes available, since they read these directly,
+         instead of just taking the characters returned by the X
+         server. This means that Wine now needs to have a mapping
+         from X keys to the scancodes these programs expect.
+       </para>
+       <para>
+         On startup, Wine will try to recognize the active X layout
+         by seeing if it matches any of the defined tables. If it
+         does, everything is alright. If not, you need to define it.
+       </para>
+       <para>
+         To do this, open the file
+         <filename>dlls/x11drv/keyboard.c</filename> and take a look
+         at the existing tables. Make a backup copy of it, especially
+         if you don't use CVS.
+       </para>
+       <para>
+         What you really would need to do, is find out which scancode
+         each key needs to generate.  Find it in the
+         <function>main_key_scan</function> table, which looks like
+         this:
+       </para>
+       <programlisting>
+static const int main_key_scan[MAIN_LEN] =
+{
+/* this is my (102-key) keyboard layout, sorry if it doesn't quite match yours */
+0x29,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,
+0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,
+0x1E,0x1F,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x2B,
+0x2C,0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,0x35,
+0x56 /* the 102nd key (actually to the right of l-shift) */
+};
+       </programlisting>
+       <para>
+         Next, assign each scancode the characters imprinted on the
+         keycaps. This was done (sort of) for the US 101-key keyboard,
+         which you can find near the top in
+         <filename>keyboard.c</filename>. It also shows that if there
+         is no 102nd key, you can skip that.
+       </para>
+       <para>
+         However, for most international 102-key keyboards, we have
+         done it easy for you. The scancode layout for these already
+         pretty much matches the physical layout in the
+         <function>main_key_scan</function>, so all you need to do is
+         to go through all the keys that generate characters on your
+         main keyboard (except spacebar), and stuff those into an
+         appropriate table. The only exception is that the 102nd key,
+         which is usually to the left of the first key of the last
+         line (usually <keycap>Z</keycap>), must be placed on a
+         separate line after the last line.
+       </para>
+       <para>
+         For example, my Norwegian keyboard looks like this
+       </para>
+       <screen>
+�  !  "  #  �  %  &  /  (  )  =  ?  `  Back-
+|  1  2@ 3� 4$ 5  6  7{ 8[ 9] 0} +  \� space
+
+Tab Q  W  E  R  T  Y  U  I  O  P  �  ^
+                            �~
+                               Enter
+Caps A  S  D  F  G  H  J  K  L  �  �  *
+Lock                                  '
+
+Sh- > Z  X  C  V  B  N  M  ;  :  _  Shift
+ift &lt;                      ,  .  -
+
+Ctrl  Alt       Spacebar       AltGr  Ctrl
+       </screen>
+       <para>
+         Note the 102nd key, which is the <keycap>&lt;></keycap> key, to
+         the left of <keycap>Z</keycap>. The character to the right of
+         the main character is the character generated by
+         <keycap>AltGr</keycap>.
+       </para>
+       <para>
+         This keyboard is defined as follows:
+       </para>
+       <programlisting>
+static const char main_key_NO[MAIN_LEN][4] =
+{
+"|�","1!","2\"@","3#�","4�$","5%","6&","7/{","8([","9)]","0=}","+?","\\�",
+"qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","��","�^~",
+"aA","sS","dD","fF","gG","hH","jJ","kK","lL","��","��","'*",
+"zZ","xX","cC","vV","bB","nN","mM",",;",".:","-_",
+"&lt;>"
+};
+       </programlisting>
+       <para>
+         Except that " and \ needs to be quoted with a backslash, and
+         that the 102nd key is on a separate line, it's pretty
+         straightforward.
+       </para>
+       <para>
+         After you have written such a table, you need to add it to the
+         <function>main_key_tab[]</function> layout index table. This
+         will look like this:
+       </para>
+       <programlisting>
+static struct {
+WORD lang, ansi_codepage, oem_codepage;
+const char (*key)[MAIN_LEN][4];
+} main_key_tab[]={
+...
+...
+{MAKELANGID(LANG_NORWEGIAN,SUBLANG_DEFAULT),  1252, 865, &amp;main_key_NO},
+...
+       </programlisting>
+       <para>
+         After you have added your table, recompile Wine and test that
+         it works. If it fails to detect your table, try running
+       </para>
+       <screen>
+WINEDEBUG=+key,+keyboard wine > key.log 2>&1
+       </screen>
+       <para>
+         and look in the resulting <filename>key.log</filename> file to
+         find the error messages it gives for your layout.
+       </para>
+       <para>
+         Note that the <constant>LANG_*</constant> and
+         <constant>SUBLANG_*</constant> definitions are in
+         <filename>include/winnls.h</filename>, which you might need
+         to know to find out which numbers your language is assigned,
+         and find it in the WINEDEBUG output. The numbers will be
+         <literal>(SUBLANG * 0x400 + LANG)</literal>, so, for example
+         the combination <literal>LANG_NORWEGIAN (0x14)</literal> and
+         <literal>SUBLANG_DEFAULT (0x1)</literal> will be (in hex)
+         <literal>14 + 1*400 = 414</literal>, so since I'm Norwegian,
+         I could look for <literal>0414</literal> in the WINEDEBUG
+         output to find out why my keyboard won't detect.
+       </para>
+      </sect2>
+    </sect1>
+  </chapter>
+
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: sgml
+sgml-parent-document:("wine-devel.sgml" "set" "book" "part" "chapter" "")
+End:
+-->