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