Implement table marshaling.
[wine/dcerpc.git] / documentation / winedev-windowing.sgml
blob8d8cccc8d28e9f4b0f6e401a8cc3b7bc478e31a1
1 <chapter>
2 <title>Windowing system</title>
3 <sect1>
4 <title>USER Module</title>
6 <para>
7 USER implements windowing and messaging subsystems. It also
8 contains code for common controls and for other
9 miscellaneous stuff (rectangles, clipboard, WNet, etc).
10 Wine USER code is located in <filename>windows/</filename>,
11 <filename>controls/</filename>, and
12 <filename>misc/</filename> directories.
13 </para>
15 <sect2>
16 <title>Windowing subsystem</title>
18 <para><filename>windows/win.c</filename></para>
19 <para><filename>windows/winpos.c</filename></para>
20 <para>
21 Windows are arranged into parent/child hierarchy with one
22 common ancestor for all windows (desktop window). Each
23 window structure contains a pointer to the immediate
24 ancestor (parent window if <constant>WS_CHILD</constant>
25 style bit is set), a pointer to the sibling (returned by
26 <function>GetWindow(..., GW_NEXT)</function>), a pointer
27 to the owner window (set only for popup window if it was
28 created with valid <varname>hwndParent</varname>
29 parameter), and a pointer to the first child window
30 (<function>GetWindow(.., GW_CHILD)</function>). All popup
31 and non-child windows are therefore placed in the first
32 level of this hierarchy and their ancestor link
33 (<varname>wnd-&gt;parent</varname>) points to the desktop
34 window.
35 </para>
36 <screen>
37 Desktop window - root window
38 | \ `-.
39 | \ `-.
40 popup -&gt; wnd1 -&gt; wnd2 - top level windows
41 | \ `-. `-.
42 | \ `-. `-.
43 child1 child2 -&gt; child3 child4 - child windows
44 </screen>
45 <para>
46 Horizontal arrows denote sibling relationship, vertical
47 lines - ancestor/child. To summarize, all windows with the
48 same immediate ancestor are sibling windows, all windows
49 which do not have desktop as their immediate ancestor are
50 child windows. Popup windows behave as topmost top-level
51 windows unless they are owned. In this case the only
52 requirement is that they must precede their owners in the
53 top-level sibling list (they are not topmost). Child
54 windows are confined to the client area of their parent
55 windows (client area is where window gets to do its own
56 drawing, non-client area consists of caption, menu,
57 borders, intrinsic scrollbars, and
58 minimize/maximize/close/help buttons).
59 </para>
60 <para>
61 Another fairly important concept is
62 <firstterm>z-order</firstterm>. It is derived from the
63 ancestor/child hierarchy and is used to determine
64 "above/below" relationship. For instance, in the example
65 above, z-order is
66 </para>
67 <screen>
68 child1-&gt;popup-&gt;child2-&gt;child3-&gt;wnd1-&gt;child4-&gt;wnd2-&gt;desktop.
69 </screen>
70 <para>
71 Current active window ("foreground window" in Win32) is
72 moved to the front of z-order unless its top-level
73 ancestor owns popup windows.
74 </para>
75 <para>
76 All these issues are dealt with (or supposed to be) in
77 <filename>windows/winpos.c</filename> with
78 <function>SetWindowPos()</function> being the primary
79 interface to the window manager.
80 </para>
81 <para>
82 Wine specifics: in default and managed mode each top-level
83 window gets its own X counterpart with desktop window
84 being basically a fake stub. In desktop mode, however,
85 only desktop window has an X window associated with it.
86 Also, <function>SetWindowPos()</function> should
87 eventually be implemented via
88 <function>Begin/End/DeferWindowPos()</function> calls and
89 not the other way around.
90 </para>
92 <sect3>
93 <title>Visible region, clipping region and update region</title>
95 <para><filename>windows/dce.c</filename></para>
96 <para><filename>windows/winpos.c</filename></para>
97 <para><filename>windows/painting.c</filename></para>
99 <screen>
100 ________________________
101 |_________ | A and B are child windows of C
102 | A |______ |
103 | | | |
104 |---------' | |
105 | | B | |
106 | | | |
107 | `------------' |
108 | C |
109 `------------------------'
110 </screen>
111 <para>
112 Visible region determines which part of the window is
113 not obscured by other windows. If a window has the
114 <constant>WS_CLIPCHILDREN</constant> style then all
115 areas below its children are considered invisible.
116 Similarly, if the <constant>WS_CLIPSIBLINGS</constant>
117 bit is in effect then all areas obscured by its siblings
118 are invisible. Child windows are always clipped by the
119 boundaries of their parent windows.
120 </para>
121 <para>
122 B has a <constant>WS_CLIPSIBLINGS</constant> style:
123 </para>
124 <screen>
125 . ______
126 : | |
127 | ,-----' |
128 | | B | - visible region of B
129 | | |
130 : `------------'
131 </screen>
132 <para>
133 When the program requests a <firstterm>display
134 context</firstterm> (DC) for a window it can specify
135 an optional clipping region that further restricts the
136 area where the graphics output can appear. This area is
137 calculated as an intersection of the visible region and
138 a clipping region.
139 </para>
140 <para>
141 Program asked for a DC with a clipping region:
142 </para>
143 <screen>
144 ______
145 ,--|--. | . ,--.
146 ,--+--' | | : _: |
147 | | B | | =&gt; | | | - DC region where the painting will
148 | | | | | | | be visible
149 `--|-----|---' : `----'
150 `-----'
151 </screen>
152 <para>
153 When the window manager detects that some part of the window
154 became visible it adds this area to the update region of this
155 window and then generates <constant>WM_ERASEBKGND</constant> and
156 <constant>WM_PAINT</constant> messages. In addition,
157 <constant>WM_NCPAINT</constant> message is sent when the
158 uncovered area intersects a nonclient part of the window.
159 Application must reply to the <constant>WM_PAINT</constant>
160 message by calling the
161 <function>BeginPaint()</function>/<function>EndPaint()</function>
162 pair of functions. <function>BeginPaint()</function> returns a DC
163 that uses accumulated update region as a clipping region. This
164 operation cleans up invalidated area and the window will not
165 receive another <constant>WM_PAINT</constant> until the window
166 manager creates a new update region.
167 </para>
168 <para>
169 A was moved to the left:
170 </para>
171 <screen>
172 ________________________ ... / C update region
173 |______ | : .___ /
174 | A |_________ | =&gt; | ...|___|..
175 | | | | | : | |
176 |------' | | | : '---'
177 | | B | | | : \
178 | | | | : \
179 | `------------' | B update region
180 | C |
181 `------------------------'
182 </screen>
183 <para>
184 Windows maintains a display context cache consisting of
185 entries that include the DC itself, the window to which
186 it belongs, and an optional clipping region (visible
187 region is stored in the DC itself). When an API call
188 changes the state of the window tree, window manager has
189 to go through the DC cache to recalculate visible
190 regions for entries whose windows were involved in the
191 operation. DC entries (DCE) can be either private to the
192 window, or private to the window class, or shared
193 between all windows (Windows 3.1 limits the number of
194 shared DCEs to 5).
195 </para>
196 </sect3>
197 </sect2>
199 <sect2>
200 <title>Messaging subsystem</title>
202 <para><filename>windows/queue.c</filename></para>
203 <para><filename>windows/message.c</filename></para>
205 <para>
206 Each Windows task/thread has its own message queue - this
207 is where it gets messages from. Messages can be:
208 <orderedlist>
209 <listitem>
210 <para>
211 generated on the fly (<constant>WM_PAINT</constant>,
212 <constant>WM_NCPAINT</constant>,
213 <constant>WM_TIMER</constant>)
214 </para>
215 </listitem>
216 <listitem>
217 <para>
218 created by the system (hardware messages)
219 </para>
220 </listitem>
221 <listitem>
222 <para>
223 posted by other tasks/threads (<function>PostMessage</function>)
224 </para>
225 </listitem>
226 <listitem>
227 <para>
228 sent by other tasks/threads (<function>SendMessage</function>)
229 </para>
230 </listitem>
231 </orderedlist>
232 </para>
233 <para>
234 Message priority:
235 </para>
236 <para>
237 First the system looks for sent messages, then for posted
238 messages, then for hardware messages, then it checks if
239 the queue has the "dirty window" bit set, and, finally, it
240 checks for expired timers. See
241 <filename>windows/message.c</filename>.
242 </para>
243 <para>
244 From all these different types of messages, only posted
245 messages go directly into the private message queue.
246 System messages (even in Win95) are first collected in the
247 system message queue and then they either sit there until
248 <function>Get/PeekMessage</function> gets to process them
249 or, as in Win95, if system queue is getting clobbered, a
250 special thread ("raw input thread") assigns them to the
251 private queues. Sent messages are queued separately and
252 the sender sleeps until it gets a reply. Special messages
253 are generated on the fly depending on the window/queue
254 state. If the window update region is not empty, the
255 system sets the <constant>QS_PAINT</constant> bit in the
256 owning queue and eventually this window receives a
257 <constant>WM_PAINT</constant> message
258 (<constant>WM_NCPAINT</constant> too if the update region
259 intersects with the non-client area). A timer event is
260 raised when one of the queue timers expire. Depending on
261 the timer parameters <function>DispatchMessage</function>
262 either calls the callback function or the window
263 procedure. If there are no messages pending the
264 task/thread sleeps until messages appear.
265 </para>
266 <para>
267 There are several tricky moments (open for discussion) -
268 </para>
270 <itemizedlist>
271 <listitem>
272 <para>
273 System message order has to be honored and messages
274 should be processed within correct task/thread
275 context. Therefore when <function>Get/PeekMessage</function> encounters
276 unassigned system message and this message appears not
277 to be for the current task/thread it should either
278 skip it (or get rid of it by moving it into the
279 private message queue of the target task/thread -
280 Win95, AFAIK) and look further or roll back and then
281 yield until this message gets processed when system
282 switches to the correct context (Win16). In the first
283 case we lose correct message ordering, in the second
284 case we have the infamous synchronous system message
285 queue. Here is a post to one of the OS/2 newsgroup I
286 found to be relevant:
287 </para>
288 <blockquote>
289 <attribution>by David Charlap</attribution>
290 <para>
291 " Here's the problem in a nutshell, and there is no
292 good solution. Every possible solution creates a
293 different problem.
294 </para>
295 <para>
296 With a windowing system, events can go to many
297 different windows. Most are sent by applications or
298 by the OS when things relating to that window happen
299 (like repainting, timers, etc.)
300 </para>
301 <para>
302 Mouse input events go to the window you click on
303 (unless some window captures the mouse).
304 </para>
305 <para>
306 So far, no problem. Whenever an event happens, you
307 put a message on the target window's message queue.
308 Every process has a message queue. If the process
309 queue fills up, the messages back up onto the system
310 queue.
311 </para>
312 <para>
313 This is the first cause of apps hanging the GUI. If
314 an app doesn't handle messages and they back up into
315 the system queue, other apps can't get any more
316 messages. The reason is that the next message in
317 line can't go anywhere, and the system won't skip
318 over it.
319 </para>
320 <para>
321 This can be fixed by making apps have bigger private
322 message queues. The SIQ fix does this. PMQSIZE does
323 this for systems without the SIQ fix. Applications
324 can also request large queues on their own.
325 </para>
326 <para>
327 Another source of the problem, however, happens when
328 you include keyboard events. When you press a key,
329 there's no easy way to know what window the
330 keystroke message should be delivered to.
331 </para>
332 <para>
333 Most windowing systems use a concept known as
334 "focus". The window with focus gets all incoming
335 keyboard messages. Focus can be changed from window
336 to window by apps or by users clicking on windows.
337 </para>
338 <para>
339 This is the second source of the problem. Suppose
340 window A has focus. You click on window B and start
341 typing before the window gets focus. Where should
342 the keystrokes go? On the one hand, they should go
343 to A until the focus actually changes to B. On the
344 other hand, you probably want the keystrokes to go
345 to B, since you clicked there first.
346 </para>
347 <para>
348 OS/2's solution is that when a focus-changing event
349 happens (like clicking on a window), OS/2 holds all
350 messages in the system queue until the focus change
351 actually happens. This way, subsequent keystrokes
352 go to the window you clicked on, even if it takes a
353 while for that window to get focus.
354 </para>
355 <para>
356 The downside is that if the window takes a real long
357 time to get focus (maybe it's not handling events,
358 or maybe the window losing focus isn't handling
359 events), everything backs up in the system queue and
360 the system appears hung.
361 </para>
362 <para>
363 There are a few solutions to this problem.
364 </para>
365 <para>
366 One is to make focus policy asynchronous. That is,
367 focus changing has absolutely nothing to do with the
368 keyboard. If you click on a window and start typing
369 before the focus actually changes, the keystrokes go
370 to the first window until focus changes, then they
371 go to the second. This is what X-windows does.
372 </para>
373 <para>
374 Another is what NT does. When focus changes,
375 keyboard events are held in the system message
376 queue, but other events are allowed through. This is
377 "asynchronous" because the messages in the system
378 queue are delivered to the application queues in a
379 different order from that with which they were
380 posted. If a bad app won't handle the "lose focus"
381 message, it's of no consequence - the app receiving
382 focus will get its "gain focus" message, and the
383 keystrokes will go to it.
384 </para>
385 <para>
386 The NT solution also takes care of the application
387 queue filling up problem. Since the system delivers
388 messages asynchronously, messages waiting in the
389 system queue will just sit there and the rest of the
390 messages will be delivered to their apps.
391 </para>
392 <para>
393 The OS/2 SIQ solution is this: When a
394 focus-changing event happens, in addition to
395 blocking further messages from the application
396 queues, a timer is started. When the timer goes
397 off, if the focus change has not yet happened, the
398 bad app has its focus taken away and all messages
399 targeted at that window are skipped. When the bad
400 app finally handles the focus change message, OS/2
401 will detect this and stop skipping its messages.
402 </para>
404 <para>
405 As for the pros and cons:
406 </para>
407 <para>
408 The X-windows solution is probably the easiest. The
409 problem is that users generally don't like having to
410 wait for the focus to change before they start
411 typing. On many occasions, you can type and the
412 characters end up in the wrong window because
413 something (usually heavy system load) is preventing
414 the focus change from happening in a timely manner.
415 </para>
416 <para>
417 The NT solution seems pretty nice, but making the
418 system message queue asynchronous can cause similar
419 problems to the X-windows problem. Since messages
420 can be delivered out of order, programs must not
421 assume that two messages posted in a particular
422 order will be delivered in that same order. This
423 can break legacy apps, but since Win32 always had an
424 asynchronous queue, it is fair to simply tell app
425 designers "don't do that". It's harder to tell app
426 designers something like that on OS/2 - they'll
427 complain "you changed the rules and our apps are
428 breaking."
429 </para>
430 <para>
431 The OS/2 solution's problem is that nothing happens
432 until you try to change window focus, and then wait
433 for the timeout. Until then, the bad app is not
434 detected and nothing is done."
435 </para>
436 </blockquote>
437 </listitem>
439 <listitem>
440 <para>
441 Intertask/interthread
442 <function>SendMessage</function>. The system has to
443 inform the target queue about the forthcoming message,
444 then it has to carry out the context switch and wait
445 until the result is available. Win16 stores necessary
446 parameters in the queue structure and then calls
447 <function>DirectedYield()</function> function.
448 However, in Win32 there could be several messages
449 pending sent by preemptively executing threads, and in
450 this case <function>SendMessage</function> has to
451 build some sort of message queue for sent messages.
452 Another issue is what to do with messages sent to the
453 sender when it is blocked inside its own
454 <function>SendMessage</function>.
455 </para>
456 </listitem>
457 </itemizedlist>
458 </sect2>
459 <sect2 id="accel-impl">
460 <title>Accelerators</title>
462 <para>
463 There are <emphasis>three</emphasis> differently sized
464 accelerator structures exposed to the user:
465 </para>
466 <orderedlist>
467 <listitem>
468 <para>
469 Accelerators in NE resources. This is also the internal
470 layout of the global handle <type>HACCEL</type> (16 and
471 32) in Windows 95 and Wine. Exposed to the user as Win16
472 global handles <type>HACCEL16</type> and
473 <type>HACCEL32</type> by the Win16/Win32 API.
474 These are 5 bytes long, with no padding:
475 <programlisting>
476 BYTE fVirt;
477 WORD key;
478 WORD cmd;
479 </programlisting>
480 </para>
481 </listitem>
482 <listitem>
483 <para>
484 Accelerators in PE resources. They are exposed to the
485 user only by direct accessing PE resources. These have a
486 size of 8 bytes:
487 </para>
488 <programlisting>
489 BYTE fVirt;
490 BYTE pad0;
491 WORD key;
492 WORD cmd;
493 WORD pad1;
494 </programlisting>
495 </listitem>
496 <listitem>
497 <para>
498 Accelerators in the Win32 API. These are exposed to the
499 user by the <function>CopyAcceleratorTable</function>
500 and <function>CreateAcceleratorTable</function> functions
501 in the Win32 API.
502 These have a size of 6 bytes:
503 </para>
504 <programlisting>
505 BYTE fVirt;
506 BYTE pad0;
507 WORD key;
508 WORD cmd;
509 </programlisting>
510 </listitem>
511 </orderedlist>
513 <para>
514 Why two types of accelerators in the Win32 API? We can only
515 guess, but my best bet is that the Win32 resource compiler
516 can/does not handle struct packing. Win32 <type>ACCEL</type>
517 is defined using <function>#pragma(2)</function> for the
518 compiler but without any packing for RC, so it will assume
519 <function>#pragma(4)</function>.
520 </para>
521 </sect2>
522 </sect1>
523 <sect1>
524 <title>X Windows System interface</title>
525 <para></para>
526 <sect2>
527 <title>Keyboard mapping</title>
528 <para>
529 Wine now needs to know about your keyboard layout. This
530 requirement comes from a need from many apps to have the
531 correct scancodes available, since they read these directly,
532 instead of just taking the characters returned by the X
533 server. This means that Wine now needs to have a mapping
534 from X keys to the scancodes these programs expect.
535 </para>
536 <para>
537 On startup, Wine will try to recognize the active X layout
538 by seeing if it matches any of the defined tables. If it
539 does, everything is alright. If not, you need to define it.
540 </para>
541 <para>
542 To do this, open the file
543 <filename>dlls/x11drv/keyboard.c</filename> and take a look
544 at the existing tables. Make a backup copy of it, especially
545 if you don't use CVS.
546 </para>
547 <para>
548 What you really would need to do, is find out which scancode
549 each key needs to generate. Find it in the
550 <function>main_key_scan</function> table, which looks like
551 this:
552 </para>
553 <programlisting>
554 static const int main_key_scan[MAIN_LEN] =
556 /* this is my (102-key) keyboard layout, sorry if it doesn't quite match yours */
557 0x29,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,
558 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,
559 0x1E,0x1F,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x2B,
560 0x2C,0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,0x35,
561 0x56 /* the 102nd key (actually to the right of l-shift) */
563 </programlisting>
564 <para>
565 Next, assign each scancode the characters imprinted on the
566 keycaps. This was done (sort of) for the US 101-key keyboard,
567 which you can find near the top in
568 <filename>keyboard.c</filename>. It also shows that if there
569 is no 102nd key, you can skip that.
570 </para>
571 <para>
572 However, for most international 102-key keyboards, we have
573 done it easy for you. The scancode layout for these already
574 pretty much matches the physical layout in the
575 <function>main_key_scan</function>, so all you need to do is
576 to go through all the keys that generate characters on your
577 main keyboard (except spacebar), and stuff those into an
578 appropriate table. The only exception is that the 102nd key,
579 which is usually to the left of the first key of the last
580 line (usually <keycap>Z</keycap>), must be placed on a
581 separate line after the last line.
582 </para>
583 <para>
584 For example, my Norwegian keyboard looks like this
585 </para>
586 <screen>
587 § ! " # ¤ % & / ( ) = ? ` Back-
588 | 1 2@ 3£ 4$ 5 6 7{ 8[ 9] 0} + \´ space
590 Tab Q W E R T Y U I O P Å ^
592 Enter
593 Caps A S D F G H J K L Ø Æ *
594 Lock '
596 Sh- > Z X C V B N M ; : _ Shift
597 ift &lt; , . -
599 Ctrl Alt Spacebar AltGr Ctrl
600 </screen>
601 <para>
602 Note the 102nd key, which is the <keycap>&lt;></keycap> key, to
603 the left of <keycap>Z</keycap>. The character to the right of
604 the main character is the character generated by
605 <keycap>AltGr</keycap>.
606 </para>
607 <para>
608 This keyboard is defined as follows:
609 </para>
610 <programlisting>
611 static const char main_key_NO[MAIN_LEN][4] =
613 "","1!","2\"@","3#£","4¤$","5%","6&","7/{","8([","9)]","0=}","+?","\\´",
614 "qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","åÅ","¨^~",
615 "aA","sS","dD","fF","gG","hH","jJ","kK","lL","øØ","æÆ","'*",
616 "zZ","xX","cC","vV","bB","nN","mM",",;",".:","-_",
617 "&lt;>"
619 </programlisting>
620 <para>
621 Except that " and \ needs to be quoted with a backslash, and
622 that the 102nd key is on a separate line, it's pretty
623 straightforward.
624 </para>
625 <para>
626 After you have written such a table, you need to add it to the
627 <function>main_key_tab[]</function> layout index table. This
628 will look like this:
629 </para>
630 <programlisting>
631 static struct {
632 WORD lang, ansi_codepage, oem_codepage;
633 const char (*key)[MAIN_LEN][4];
634 } main_key_tab[]={
637 {MAKELANGID(LANG_NORWEGIAN,SUBLANG_DEFAULT), 1252, 865, &amp;main_key_NO},
639 </programlisting>
640 <para>
641 After you have added your table, recompile Wine and test that
642 it works. If it fails to detect your table, try running
643 </para>
644 <screen>
645 WINEDEBUG=+key,+keyboard wine > key.log 2>&1
646 </screen>
647 <para>
648 and look in the resulting <filename>key.log</filename> file to
649 find the error messages it gives for your layout.
650 </para>
651 <para>
652 Note that the <constant>LANG_*</constant> and
653 <constant>SUBLANG_*</constant> definitions are in
654 <filename>include/winnls.h</filename>, which you might need
655 to know to find out which numbers your language is assigned,
656 and find it in the WINEDEBUG output. The numbers will be
657 <literal>(SUBLANG * 0x400 + LANG)</literal>, so, for example
658 the combination <literal>LANG_NORWEGIAN (0x14)</literal> and
659 <literal>SUBLANG_DEFAULT (0x1)</literal> will be (in hex)
660 <literal>14 + 1*400 = 414</literal>, so since I'm Norwegian,
661 I could look for <literal>0414</literal> in the WINEDEBUG
662 output to find out why my keyboard won't detect.
663 </para>
664 </sect2>
665 </sect1>
666 </chapter>
668 <!-- Keep this comment at the end of the file
669 Local variables:
670 mode: sgml
671 sgml-parent-document:("wine-devel.sgml" "set" "book" "part" "chapter" "")
672 End: