Wine Traffic #3 For 11 Jul 1999
Table Of Contents
Introduction
This is the third release of the experimental Wine's kernel cousin publication.
It's main goal is to distribute widely what's going on around Wine (the Un*x
windows emulator).
Wine Weekly News has made its way
to winehq.com. You'll find there the merge of Ove's effort and these KC
cousin pages.
Jutta Wrage is currently updating the Wine HOWTO with printing
information.
Douglas Ridgway posted the Wine
presentation intented for the O'Reilly Open Source Symposium, August
21-24, in Monterey, CA.
1.
DIBs rendering and speed up
Archive Link: "XShmemdibs, Corel"
People:
Alexander Larsson, Zygo Blaxell, , Gavriel State
Alexander Larsson was seeing performance problems with Device Independent
Bitmaps, and he inquired: I'm not very good
at Win32, but i would like to add support for using MIT XShmem images for
dibs. I've asked some core developers about this, and they said Corel was
working on this. Is this true? How far from finished is it?
Gavriel State explained the current state of this patch (Karl Lessard had
written it, but it had not yet been reviewed enough to be sent to
wine-patches).
Zygo Blaxell, even though he was busy moving house, took the time to send
the patch in its current state to wine-devel, with the following warning:
Disclaimer: I scraped this patch together in the
last ~45 minutes or so. The following code appears to run 'sol.exe' without
segfaulting. This is the _only_ thing I'm willing to say about it. This is
the first time in a couple of weeks that this code has actually worked at
all for me, so I don't know yet if it's still chock full o' bugs.
Alexander added the next day: Cool. After
some minor changes i actually got a fairly large speedup. Went from maybe 10
seconds per frame to about 1 second per frame. I'll do some further
optimization, profiling and clean-up tomorrow.
Alexander Larsson then posted to wine-devel the result
of his first shot at the patch, asking Corel if they wanted to clean it
up and/or to submit to wine-patches.
Gavriel State answered that Alexander could do it if he had the time, Corel
poeple were more concentrating on porting issues right now, and it'd be
better (and quicker) if Alexander took care of the clean-up. The patch has
not yet made its way to wine-patches.
2.
elfdll and binding
Archive Link: "elfdll stuff"
People:
Ulrich Weigand, , Alexander Larsson
Alexander Larsson proposed his experience in export symbol handling to be
used in Wine (mainly by exporting symbols in a specific way (either in a non
standard section or by marking them)).
Ulrich Weigand reminded that:
one of the requirements of the elfdll
import/export handling is that is should transparently work between elfdll
and PE modules, so that within the whole executable, DLLs can be arbitrarily
replaced by PE or elfdll versions, and all imports/export still work.
This means that not only the non-exported symbols should not be available
for ELF linking, but rather *no* symbols at all should use ELF linking,
because the side being linked to might be PE.
So, Bertho's current experimental dllglue works like this: link everything
belonging to one elfdll into an object, use the symbol table of the object
together with the .spec files defining the exports of the various DLLs to
create a PE header containing both an exports and an imports table, link the
PE header into the object (thereby resolving all symbols originally imported
by the elfdll to IAT stubs) and finally localize all ELF symbols (except one
symbol pointing to the PE header itself).
Thus, you get a .so file which the Wine loader loads using dlopen(),
retrieves the PE header using dlsym(), and performs the usual PE
import/export resolving.
Ulrich nevertheless pointed to some areas that could be enhanced:
- On the export side, it might be possible to avoid the necessity
for an specific .spec file if the symbols intended to be exported
could be marked in the source using a technique similar to the ones
you mentioned.
- On the import side, we could avoid the necessity for assembly
glue code stubs if the compiler could be told that calls to an
imported function should be coded as *indirect* calls, with the
imported symbol actually pointing to a *pointer* to the function.
This is exactly what the 'declspec(dllimport)' of MS compilers
does.
Alexander said that Mozilla and Cygnus were willing to add the needed
support for "Export side" in egcs, but this wouldn't be present in egcs
2.95.
On the "Import side", Alexander suggested to directly tweak with the GOT
(Global Offset Table) [editor's note: the GOT is used to relocate symbols
from an .so library on loading].
Both Ulrich and Bertho's Stultiens agreed this was not a very good solution
because it was non portable (because use of assembly language and too much
knowledge of .so internals were required) and it couldn't solve some elfdll
specific issues (like importing two functions of same name from two
different DLLs).
3.
controls and painting
Archive Link: "scrollbar"
People:
Dennis Björklund, Girard Patel, Dennis Bjvrklund, , Gérard Patel
Dennis Björklund reported some issues he had (and provided a sample program
to demonstrate them).
- The file selection dialog does not work. Nothing happens when I press OK
even if I have selected a file.
(press left mouse button in my test example)
- The scrollbar does not work when it is being draged. When I release the
scrollbar it jumps back to the top.
- There is a graphical problem with the scrollbar. The edges of the
control is corrupted. I expected it to have a win95/98 look (I have
WineLook=Win98 in ~/.winerc). But it does not look like it does in
windows. Is it not implemented or do I do something wrong?
- The application icon does not exist. All I get is a blank square. I
guess that it's just a bitmap that's missing but I report it anyways
since it is a bug.
The code is: LoadIcon( NULL, IDI_APPLICATION )
Gérard Patel answered point by point:
- 1/ Yes it's hosed. The Wine code here is a bit difficult to understand,
though. I am not sure than fixing it will not lead to worse problems. If I
had all the time in the world I would like to rewrite it. I guess that the
motivation to fix it is gone now than people can use the so-called 'native'
(read : BillG) controls. I think (but I am not sure at all) that somewhere
someone hinted to want to write a 32 bit version of these openfile controls,
so maybe this will be fixed. Corel will need it anyway, so all hope is not
lost.
- 2&3/ It's a recent problem. I intend to attack some scrollbar problems
real soon now. Wether I will win or the scrollbar will win is an open
question. I will probably try your code while I'm at it. In a week or
two.
- 4/ I have no intention to look at this problem soon, sorry.
Dennis then applied Gérard's patches and replied: My scrollbar problem that has been there for a long time has gone
away with wine-990704.
But, he also noticed (after diving into the code) that there is still a lot of (graphical) problems with the scrollbars
in win9x mode. So I started to fix some small problems. And since I have
some free weeks now in the sommer I could spend some time fixing the
scrollbars for real.
and asked wether someone else was also looking
at those issues.
Gérard answered he was focusing on some other areas, but reminded a
few guidelines:
- scrollbars are used everywhere, breaking something with them should be
real easy. I don't know how much code there is in Wine, but it could be near
one million of lines...Enough to make it difficult to find where is the
change that broke something.
- if you want to pass just a few weeks on wine development and then pass
to other things, please forget it. Problems could surface after you are gone
and then who will be left to fix things you could have broken ??? Do changes
only if you offer support :-)
Dennis agreed on the guidelines and went on, with Gérard, on a more in depth
discussion of the current state of the graphical behavior of scrollbars (and
fixme:s in the code).
4.
DLLs loading
Archive Link: "Your opinion"
People:
Michele Petrovsky, Ulrich Weigand,
Michele Petrovsky, the one who is writing the book regarding Wine admin,
asked about a a generalized statement of the
impact of controlling load order of DLLs in creating the WINE runtime.
Beyond, of course, the idea that loading native Windows DLLs before built-in
ones can tweak application performance. Are there areas of app behavior (for
example, multimedia or data communications) for which this rule-of-thumb
*doesn't* hold true? Or are there types of apps which might benefit more
from attempting, for instance, to load a special DLL first?
Ulrich Weigand gave a full answer regarding DLL loading, load order and al.
Well, the problem is that you can *not* simply
say 'native DLLs are better' or 'built-in DLLs are better'. There are
basically two aspects to be considered that tend to contradict each other:
- On the one hand, native DLLs of course guarantee 100% compatibility for
those routines they implement. Examples: If you use native USER, the
visual appearance of window borders, dialog controls etc. is more-or-less
perfect, if you use built-in USER, it doesn't really look quite like
Windows 95 ... Same holds for the common controls (COMMCTRL) or the common
dialogs (COMMDLG). The native SHELL contains e.g. the routines used by
installers to create desktop shortcuts; since the file format of a
shortcut file is not documented, Wine doesn't correctly implement these
routines yet, hence some installers might fail when using built-in
SHELL.
- On the other hand, a native DLL might try to access features of the rest
of the system which are not quite correctly implemented in Wine (e.g.
because they are undocumented). In this case, the native DLL might work
much worse than the built-in one, or even not all. Examples: The native
MPR requires shared PE sections to work, which is not yet supported by
Wine, hence it doesn't run. The native GDI requires a Windows display
driver to be present, which isn't the case under Wine. The native KERNEL
doesn't work at all because it directly accesses the Win95 core which
isn't there under Wine.
- A probably minor point: In a few cases, the Wine built-in DLLs implement
*more* features than the original Windows DLLs; these features will not
work when using the native DLLs, of course. The one prime example of this
is the integration of Wine with X provided by built-in USER; if you use
native USER, you can only run Wine in -desktop mode, and using the
clipboard or drag-and-drop between Wine windows and X windows will not
work.
So, unfortunately, there is no rule-of-thumb which load-order to use; you'll
have to have a certain knowledge of what the DLL in question does, which
other DLLs/features it requires etc. to make a case-by-case decision. For
most users, it will probably be best to simply stay with the load-order
settings laid out the the default wine.ini file. This default setting is
determined as follows: for all DLLs where there is a proper Wine
implementation at all (i.e. not just stubs), or where the native DLL is
known *not* to work, use built-in first. All others, use native.
If you do want to experiment with variations of the load-order settings,
there are two fixed rules that must be complied with:
- Always use the same setting for DLL pairs (i.e. the 16-bit and 32-bit
DLL that form a tightly integrated whole). You can use both native COMMDLG
and COMDLG32 or both built-in, but don't try to mix it. The same holds for
the other DLLs listed in the [DllPairs] section.
- If DLL A calls routines of DLL B, and you use the native version of DLL
B, you *must* also use the native version of DLL A. [This will no longer
be required once the elf-dll mechanism works.] Normally, this is only a
concern when using native USER.
Some candidates where it might be worth-while to try deviating from the
standard setting (built-in) and use the native version would be:
- SHELL/SHELL32
- COMMCTRL/COMCTL32
- COMMDLG/COMDLG32
The native versions of these seem to work quite well nowadays, and they tend
to bring noticeable improvements over the built-in ones. But, of course,
YMMV ;-)
If you are especially daring, you might also try to use native USER/USER32
(if you do this, you *must* also use the native versions of the DLLs
mentioned above). You'll have to live with the drawbacks (only -desktop
mode, etc), but in some cases it does have advantages: e.g. some
InstallShield apps run better with native USER, and if you are very lucky,
you might even get Explorer to run a little ...
Lots of people were very happy with this description and requested it
to be added to the documentation directory.
5.
Porting to non-Intel architectures
Archive Link: "Non-Intel library fixes and Win64"
People:
Alexander Larsson, , Patrik Stridvall
Patrik Stridvall sent a patch to wine-patches to let Winelib compile on
non-Intel platforms (including 64 bit ones). (Editor note: Intel platform
means i?86 and Pentium (I, II, III). Merced, when available, should be
considered as non Intel in the following article :-/).
Alexander Larsson rejected it because Making
it compile is good, but making it work would be better ;-) I'm not going to
apply patches that simply remove everything that doesn't compile. This is
especially important since few people have access to these other platforms,
so if you don't do the job nobody else will.
So, Alexandre added a #error in the CONTEXT
struct definition: to clearly mark that there is something here that you
must think about when porting. I could have put in a dummy struct instead,
it would have compiled just fine, and it would only have been fixed after
someone spent hours trying to figure out why some obscure API function
doesn't work right. I think a clear compile-time error is
preferable.
Patrik asked why there wasn't any alike #error in the library part to bark
at compile time when __i386__ was not defined.
Alexandre agreed and ended the thread with all the
places that need a portable CONTEXT (mostly the exception stuff) will
eventually have a #error added.
6.
Porting to BeOS
Archive Link: "A small step towards portability"
People:
Howard Abrams, Ulrich Weigand, , Marcus Meissner
Howard Abrams sent to wine-patches some configuration stuff that helps Wine
compile on BeOS.
Marcus Meissner provided some improvement on the patch and asked wether BeOS
was supporting mmap().
Howard answered there is talk about it for R5,
not sure if it will happen.
Howard also explained that his previous attempts at porting show that Be was
missing some important calls (like mmap, socketpair, select() on file
descriptors, send/recvmsg). He now wants to tackle the porting issue on a
step by step approach, and may be requiring some feedback from Be, which
stated they'd tend to be more and more Posix compliant.
Ulrich and Howard then discussed the different points. mmap() could be
implemented by reading all the file into memory (which would result in bad
performances with MapViewOfFile on large files). mmap() is also now used as
an improvement for passing data back and forth to the server (instead of
sending them through the pipe); Ulrich asked wether a shared memory feature
exists on Be? Howard said yes: Areas.
Ulrich reminded that the current server implementation requires you need to be able to pass *file descriptors* over the
pipe. This means that the server opens a file, passes the descriptor to the
client, and the client then uses the descriptor to access the file. Of
course, you cannot simply pass the numerical value of the descriptor,
because the client is another process. Thus, we use a special feature of
sockets that allows to pass open file descriptors ('access rights'). This is
the reason for using sendmsg() instead of sendto() in the first
place!
Ulrich pinpointed the known troubleshooter while porting to other Unices:
thread support, address spaces,
Howard asked about using Be native synchronization methods. Ulrich
listed all the objects Win32 sync methods were able to wait on:
- signalled synchronization objects (semaphores, events, mutexes)
- process or thread termination
- I/O activity (files, pipes, sockets, mailslots)
- Console I/O
- file-change notifications
and explained how the Wine server did this job:
Thus, in Wine the thread calling WaitForMultipleObjects simply blocks on the
socket to the server. It stays blocked until the server has decided that the
wait condition is satisfied (it can do so because all actions relevant to
the status of the objects waited on is reported to the server, either by the
(other) clients or by the OS as a result of the main select() call), and
then wakes the client up by sending the reply to the original
message.
From a Unix stand point, WaitForMultipleObjects has to wait on:
- "real file" descriptors
- pipes
- connection to the X server
- in a (near future) on network connections
Regarding the LDT (Local Descriptor Table), Ulrich said:
That's the Intel processor data structure used
to define segments. Linux normally uses only one single data segment and a
single code segment, both spanning the complete address space from 0 to 4
GB. All segment registers are usually set up by the OS on process startup
with these values and never changed by the program. Thus, the illusion of a
non-segmented address space is created, although the Intel processor
actually *always* uses a segmented address space ;-)
Wine, however, needs to define additional segments for its own use. This is
obvious when executing 16-bit code, but is even necessary when executing
Win32 processes (e.g. the TEB selector must be loaded into the %fs
register).
As accessing the LDT directly is protected, we need to use special system
calls to do so (modify_ldt() on Linux, i386_set_ldt() on *BSD, and
sysi86(SI86DSCR, ...) on Solaris/x86). So, the question is:
- Does BeOS provide an analogous syscall at all?
- Are the LDT settings shared for all threads in one address space (if
they aren't, Wine won't work. This is broken on Linux 2.0.*)
- Does the BeOS environment survive if segments are actually used? This
means:
- Can the libraries cope if they are called with segment registers %fs,%gs
set up different than usual (e.g. the Solaris/x86 thread libraries crashed
when the application modified the %gs segment register ...)
- What happens when executing code in a 16-bit segment and/or with the
stack in a 16-bit segment at the time an interrupt/signal/... needs to be
processed by the OS?
- Are the values of the segment registers preserved over process
switches?
Sharon And Joy