|  | <chapter id="architecture"> | 
|  | <title>Overview</title> | 
|  | <para>Brief overview of Wine's architecture...</para> | 
|  |  | 
|  | <sect1 id="basic-overview"> | 
|  | <title>Basic Overview</title> | 
|  |  | 
|  | <para> | 
|  | With the fundamental architecture of Wine stabilizing, and | 
|  | people starting to think that we might soon be ready to | 
|  | actually release this thing, it may be time to take a look at | 
|  | how Wine actually works and operates. | 
|  | </para> | 
|  |  | 
|  | <sect2> | 
|  | <title>Wine Overview</title> | 
|  | <para> | 
|  | Wine is often used as a recursive acronym, standing for | 
|  | "Wine Is Not an Emulator". Sometimes it is also known to be | 
|  | used for "Windows Emulator". In a way, both meanings are | 
|  | correct, only seen from different perspectives. The first | 
|  | meaning says that Wine is not a virtual machine, it does not | 
|  | emulate a CPU, and you are not supposed to install | 
|  | Windows nor any Windows device drivers on top of it; rather, | 
|  | Wine is an implementation of the Windows API, and can be | 
|  | used as a library to port Windows applications to Unix. The | 
|  | second meaning, obviously, is that to Windows binaries | 
|  | (<filename>.exe</filename> files), Wine does look like | 
|  | Windows, and emulates its behaviour and quirks rather | 
|  | closely. | 
|  | </para> | 
|  | <note> | 
|  | <title>Note</title> | 
|  | <para> | 
|  | The "Emulator" perspective should not be thought of as if | 
|  | Wine is a typical inefficient emulation layer that means | 
|  | Wine can't be anything but slow - the faithfulness to the | 
|  | badly designed Windows API may of course impose a minor | 
|  | overhead in some cases, but this is both balanced out by | 
|  | the higher efficiency of the Unix platforms Wine runs on, | 
|  | and that other possible abstraction libraries (like Motif, | 
|  | GTK+, CORBA, etc) has a runtime overhead typically | 
|  | comparable to Wine's. | 
|  | </para> | 
|  | </note> | 
|  | </sect2> | 
|  |  | 
|  | <sect2> | 
|  | <title>Win16 and Win32</title> | 
|  | <para> | 
|  | Win16 and Win32 applications have different requirements; | 
|  | for example, Win16 apps expect cooperative multitasking | 
|  | among themselves, and to exist in the same address space, | 
|  | while Win32 apps expect the complete opposite, i.e. | 
|  | preemptive multitasking, and separate address spaces. | 
|  | </para> | 
|  | <para> | 
|  | Wine now deals with this issue by launching a separate Wine | 
|  | process for each Win32 process, but not for Win16 tasks. | 
|  | Win16 tasks are now run as different intersynchronized | 
|  | threads in the same Wine process; this Wine process is | 
|  | commonly known as a <firstterm>WOW</firstterm> process, | 
|  | referring to a similar mechanism used by Windows NT. | 
|  | Synchronization between the Win16 tasks running in the WOW | 
|  | process is normally done through the Win16 mutex - whenever | 
|  | one of them is running, it holds the Win16 mutex, keeping | 
|  | the others from running. When the task wishes to let the | 
|  | other tasks run, the thread releases the Win16 mutex, and | 
|  | one of the waiting threads will then acquire it and let its | 
|  | task run. | 
|  | </para> | 
|  | </sect2> | 
|  |  | 
|  | <sect2> | 
|  | <title>The Wine server</title> | 
|  | <para> | 
|  | The Wine server is among the most confusing concepts in Wine. | 
|  | What is its function in Wine? Well, to be brief, it provides | 
|  | Inter-Process Communication (IPC), synchronization, and | 
|  | process/thread management. When the wineserver launches, it | 
|  | creates a Unix socket for the current host based on (see below) | 
|  | your home directory's <filename>.wine</filename> subdirectory (or | 
|  | wherever the <constant>WINEPREFIX</constant> environment | 
|  | variable points) - all Wine processes launched later | 
|  | connects to the wineserver using this socket. (If a | 
|  | wineserver was not already running, the first Wine process | 
|  | will start up the wineserver in auto-terminate mode (i.e. | 
|  | the wineserver will then terminate itself once the last Wine | 
|  | process has terminated).) | 
|  | </para> | 
|  | <para> | 
|  | In earlier versions of Wine the master socket mentioned | 
|  | above was actually created in the configuration directory; | 
|  | either your home directory's <filename>/wine</filename> | 
|  | subdirectory or wherever the <constant>WINEPREFIX</constant> | 
|  | environment variable points>.  Since that might not be possible | 
|  | the socket is actually created within the <filename>/tmp</filename> | 
|  | directory with a name that reflects the configuration directory. | 
|  | This means that there can actually be several separate copies of | 
|  | the wineserver running; one per combination of user and | 
|  | configuration directory.  Note that you should not have several | 
|  | users using the same configuration directory at the same time; | 
|  | they will have different copies of the wineserver running and | 
|  | this could well lead to problems with the registry information | 
|  | that they are sharing. | 
|  | </para> | 
|  | <para> | 
|  | Every thread in each Wine process has its own request | 
|  | buffer, which is shared with the wineserver. When a thread | 
|  | needs to synchronize or communicate with any other thread or | 
|  | process, it fills out its request buffer, then writes a | 
|  | command code through the socket. The wineserver handles the | 
|  | command as appropriate, while the client thread waits for a | 
|  | reply. In some cases, like with the various | 
|  | <function>WaitFor</function> synchronization primitives, the | 
|  | server handles it by marking the client thread as waiting | 
|  | and does not send it a reply before the wait condition has | 
|  | been satisfied. | 
|  | </para> | 
|  | <para> | 
|  | The wineserver itself is a single and separate process and | 
|  | does not have its own threading - instead, it is built on | 
|  | top of a large <function>poll()</function> loop that alerts | 
|  | the wineserver whenever anything happens, such as a client | 
|  | having sent a command, or a wait condition having been satisfied. | 
|  | There is thus no danger of race conditions inside the | 
|  | wineserver itself - it is often called upon to do operations | 
|  | that look completely atomic to its clients. | 
|  | </para> | 
|  | <para> | 
|  | Because the wineserver needs to manage processes, threads, | 
|  | shared handles, synchronization, and any related issues, all | 
|  | the clients' Win32 objects are also managed by the | 
|  | wineserver, and the clients must send requests to the | 
|  | wineserver whenever they need to know any Win32 object | 
|  | handle's associated Unix file descriptor (in which case the | 
|  | wineserver duplicates the file descriptor, transmits it to | 
|  | the client, and leaves it to the client to close the duplicate | 
|  | when the client has finished with it). | 
|  | </para> | 
|  | </sect2> | 
|  |  | 
|  | <sect2> | 
|  | <title>Relays, Thunks, and DLL descriptors</title> | 
|  | <para> | 
|  | Loading a Windows binary into memory isn't that hard by | 
|  | itself, the hard part is all those various DLLs and entry | 
|  | points it imports and expects to be there and function as | 
|  | expected; this is, obviously, what the entire Wine | 
|  | implementation is all about. Wine contains a range of DLL | 
|  | implementations. Each of the implemented (or | 
|  | half-implemented) DLLs (which can be found in the | 
|  | <filename>dlls/</filename> directory) need to make | 
|  | themselves known to the Wine core through a DLL descriptor. | 
|  | These descriptors point to such things as the DLL's | 
|  | resources and the entry point table. | 
|  | </para> | 
|  | <para> | 
|  | The DLL descriptor and entry point table is generated by the | 
|  | <command>winebuild</command> tool (previously just named | 
|  | <command>build</command>), taking DLL specification files | 
|  | with the extension <filename>.spec</filename> as input. The | 
|  | output file contains a global constructor that automatically | 
|  | registers the DLL's descriptor with the Wine core at | 
|  | runtime. | 
|  | </para> | 
|  | <para> | 
|  | Once an application module wants to import a DLL, Wine will | 
|  | look through its list of registered DLLs (if it's not | 
|  | registered, it will look for it on disk). (Failing that, it | 
|  | will look for a real Windows <filename>.DLL</filename> file | 
|  | to use, and look through its imports, etc.) To resolve the | 
|  | module's imports, Wine looks through the entry point table | 
|  | and finds if it's defined there. (If not, it'll emit the | 
|  | error "No handler for ...", which, if the application called | 
|  | the entry point, is a fatal error.) | 
|  | </para> | 
|  | <para> | 
|  | Since Wine is 32-bit code itself, and if the compiler | 
|  | supports Windows' calling convention, <type>stdcall</type> | 
|  | (<command>gcc</command> does), Wine can resolve imports into | 
|  | Win32 code by substituting the addresses of the Wine | 
|  | handlers directly without any thunking layer in between. | 
|  | This eliminates the overhead most people associate with | 
|  | "emulation", and is what the applications expect anyway. | 
|  | </para> | 
|  | <para> | 
|  | However, if the user specified <parameter>--debugmsg | 
|  | +relay</parameter>, a thunk layer is inserted between the | 
|  | application imports and the Wine handlers; this layer is | 
|  | known as "relay" because all it does is print out the | 
|  | arguments/return values (by using the argument lists in the | 
|  | DLL descriptor's entry point table), then pass the call on, | 
|  | but it's invaluable for debugging misbehaving calls into | 
|  | Wine code. A similar mechanism also exists between Windows | 
|  | DLLs - Wine can optionally insert thunk layers between them, | 
|  | by using <parameter>--debugmsg +snoop</parameter>, but since | 
|  | no DLL descriptor information exists for non-Wine DLLs, this | 
|  | is less reliable and may lead to crashes. | 
|  | </para> | 
|  | <para> | 
|  | For Win16 code, there is no way around thunking - Wine needs | 
|  | to relay between 16-bit and 32-bit code. These thunks switch | 
|  | between the app's 16-bit stack and Wine's 32-bit stack, | 
|  | copies and converts arguments as appropriate, and handles | 
|  | the Win16 mutex. Suffice to say that the kind of intricate | 
|  | stack content juggling this results in, is not exactly | 
|  | suitable study material for beginners. | 
|  | </para> | 
|  | </sect2> | 
|  |  | 
|  | <sect2> | 
|  | <title>Core and non-core DLLs</title> | 
|  |  | 
|  | <!-- FIXME: Should do this without the .jpg (AJ) | 
|  | <para> | 
|  | This slide (by Marcus Meissner of Caldera Systems, shown at | 
|  | the Comdex 99) shows how Wine is meant to fit into the | 
|  | Windows DLL model. | 
|  | <mediaobject> | 
|  | <imageobject> | 
|  | <imagedata fileref="arch-layout.jpg" format="jpg"> | 
|  | </imageobject> | 
|  | </mediaobject> | 
|  | </para> | 
|  | FIXME --> | 
|  |  | 
|  | <para> | 
|  | Wine must at least completely replace the "Big Three" DLLs | 
|  | (KERNEL/KERNEL32, GDI/GDI32, and USER/USER32), which all | 
|  | other DLLs are layered on top of. But since Wine is (for | 
|  | various reasons) leaning towards the NT way of implementing | 
|  | things, the NTDLL is another core DLL to be implemented in | 
|  | Wine, and many KERNEL32 and ADVAPI32 features will be | 
|  | implemented through the NTDLL. The wineserver and the | 
|  | service thread provide the backbone for the implementation | 
|  | of these core DLLs, and integration with the X11 driver | 
|  | (which provides GDI/GDI32 and USER/USER32 functionality | 
|  | along with the Windows standard controls). All non-core | 
|  | DLLs, on the other hand, are expected to only use routines | 
|  | exported by other DLLs (and none of these backbone services | 
|  | directly), to keep the code base as tidy as possible. An | 
|  | example of this is COMCTL32 (Common Controls), which should | 
|  | only use standard GDI32- and USER32-exported routines. | 
|  | </para> | 
|  | </sect2> | 
|  | </sect1> | 
|  |  | 
|  | <sect1 id="module-overview"> | 
|  | <title>Module Overview</title> | 
|  |  | 
|  | <sect2> | 
|  | <title>KERNEL Module</title> | 
|  |  | 
|  | <para>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->parent</varname>) points to the desktop | 
|  | window. | 
|  | </para> | 
|  | <screen> | 
|  | Desktop window			- root window | 
|  | |     \      `-. | 
|  | |      \        `-. | 
|  | popup -> wnd1  ->  wnd2		- top level windows | 
|  | |       \   `-.      `-. | 
|  | |        \     `-.      `-. | 
|  | child1  child2 -> child3  child4     - child windows | 
|  | </screen> | 
|  | <para> | 
|  | Horizontal arrows denote sibling relationship, vertical | 
|  | lines - ancestor/child. To summarize, all windows with the | 
|  | same immediate ancestor are sibling windows, all windows | 
|  | which do not have desktop as their immediate ancestor are | 
|  | child windows. Popup windows behave as topmost top-level | 
|  | windows unless they are owned. In this case the only | 
|  | requirement is that they must precede their owners in the | 
|  | top-level sibling list (they are not topmost). Child | 
|  | windows are confined to the client area of their parent | 
|  | windows (client area is where window gets to do its own | 
|  | drawing, non-client area consists of caption, menu, | 
|  | borders, intrinsic scrollbars, and | 
|  | minimize/maximize/close/help buttons). | 
|  | </para> | 
|  | <para> | 
|  | Another fairly important concept is | 
|  | <firstterm>z-order</firstterm>. It is derived from the | 
|  | ancestor/child hierarchy and is used to determine | 
|  | "above/below" relationship. For instance, in the example | 
|  | above, z-order is | 
|  | </para> | 
|  | <screen> | 
|  | child1->popup->child2->child3->wnd1->child4->wnd2->desktop. | 
|  | </screen> | 
|  | <para> | 
|  | Current  active window ("foreground window" in Win32) is | 
|  | moved to the front of z-order unless its top-level | 
|  | ancestor owns popup windows. | 
|  | </para> | 
|  | <para> | 
|  | All these issues are dealt with (or supposed to be) in | 
|  | <filename>windows/winpos.c</filename> with | 
|  | <function>SetWindowPos()</function> being the primary | 
|  | interface to the window manager. | 
|  | </para> | 
|  | <para> | 
|  | Wine specifics: in default and managed mode each top-level | 
|  | window gets its own X counterpart with desktop window | 
|  | being basically a fake stub. In desktop mode, however, | 
|  | only desktop window has an X window associated with it. | 
|  | Also, <function>SetWindowPos()</function> should | 
|  | eventually be implemented via | 
|  | <function>Begin/End/DeferWindowPos()</function> calls and | 
|  | not the other way around. | 
|  | </para> | 
|  |  | 
|  | <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 |   |  => |  |    | - DC region where the painting will | 
|  | |  |     |   |     |  |    |   be visible | 
|  | `--|-----|---'     :  `----' | 
|  | `-----' | 
|  | </screen> | 
|  | <para> | 
|  | When the window manager detects that some part of the window | 
|  | became visible it adds this area to the update region of this | 
|  | window and then generates <constant>WM_ERASEBKGND</constant> and | 
|  | <constant>WM_PAINT</constant> messages.  In addition, | 
|  | <constant>WM_NCPAINT</constant> message is sent when the | 
|  | uncovered area  intersects a nonclient part of the window. | 
|  | Application must reply to the <constant>WM_PAINT</constant> | 
|  | message by calling the | 
|  | <function>BeginPaint()</function>/<function>EndPaint()</function> | 
|  | pair of functions. <function>BeginPaint()</function> returns a DC | 
|  | that uses accumulated update region as a clipping region. This | 
|  | operation cleans up invalidated area and the window will not | 
|  | receive another <constant>WM_PAINT</constant> until the window | 
|  | manager creates a new update region. | 
|  | </para> | 
|  | <para> | 
|  | A was moved to the left: | 
|  | </para> | 
|  | <screen> | 
|  | ________________________       ...          / C update region | 
|  | |______                  |     :      .___ / | 
|  | | A    |_________        |  => |   ...|___|.. | 
|  | |      |         |       |     |   :  |   | | 
|  | |------'         |       |     |   :  '---' | 
|  | |   |      B     |       |     |   :      \ | 
|  | |   |            |       |     :            \ | 
|  | |   `------------'       |                    B update region | 
|  | |                   C    | | 
|  | `------------------------' | 
|  | </screen> | 
|  | <para> | 
|  | Windows maintains a display context cache consisting of | 
|  | entries that include the DC itself, the window to which | 
|  | it belongs, and an optional clipping region (visible | 
|  | region is stored in the DC itself). When an API call | 
|  | changes the state of the window tree, window manager has | 
|  | to go through the DC cache to recalculate visible | 
|  | regions for entries whose windows were involved in the | 
|  | operation. DC entries (DCE) can be either private to the | 
|  | window, or private to the window class, or shared | 
|  | between all windows (Windows 3.1 limits the number of | 
|  | shared DCEs to 5). | 
|  | </para> | 
|  | </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> | 
|  |  | 
|  | <!-- Keep this comment at the end of the file | 
|  | Local variables: | 
|  | mode: sgml | 
|  | sgml-parent-document:("wine-devel.sgml" "set" "book" "part" "chapter" "") | 
|  | End: | 
|  | --> |