Fw: [Mono-list] System.Windows.Forms plans.

Mike Hearn mike at navi.cx
Fri Jul 2 06:11:46 CDT 2004


On Thu, 01 Jul 2004 21:22:24 -0700, Steven Edwards wrote:
> You are asking for stable interfaces and those can only come once there
> is a Wine 1.0.

To be frank, I think we could declare Wine interface stable *today*.
Versioning APIs is not exactly rocket science, yes it implies compromises
but it's quite clear that Wine 1.0 is years away. These people want to use
it today. We have all kinds of goals for 0.9 and 1.0 mixed in together and
we seem to have decided pretty much arbitrarily that they should all occur
at once, but I don't see the logic behind that.

I really feel that yes we should support Wine as a library, and that means
making the APIs we export stable ASAP. I especially think we should stop
the nonsense where we use GNU symbol versions in libwine marked "1.0"
while not actually keeping them stable.

OK, so having had that rant, I also think that not using Wine to implement
System.Windows.Forms is crazy too (hmm, there's a theme here, guess I'm
feeling contrary today). The only reason to implement SWF is to run
.NET apps built for Windows, it's a sucky toolkit compared to GTK# and
isn't going to be used for writing apps on Linux that's for sure.

Therefore perfect compatibility is crucial. SWF is a very leaky API,
there are the obvious ones like WndProc and Control.Handle but it almost
certainly leaks in other ways: for instance, the order in which events are
fired, that sort of thing. This *matters*, I've seen many apps crash
and burn in mysterious ways due to tiny differences in the order
notifications were sent to it and other subtleties.

Now, I think some of Peters arguments are valid and some aren't. Let's
take a look at them:

* Wine is too hard to use as a library. It does complicated things with
registers and threads, and requires wierd bootstrap code.

I'm not sure what to make of this one. The low level code isn't optional,
it's required in order to provide the environment Win32 code requires.
Mono likewise does some pretty complicated stuff to provide a .NET JITing
runtime so you guys are clearly competent when it comes to low level code.

If you skip the hard stuff here then you'll just hit a brick wall further
down the road when you start trying to run *real apps* which P/Invoke to
native code, poke controls via their Handles and other icky things. .NET
simply wasn't created for portability at all, regardless of what Microsoft
might say, and production .NET apps developed for Windows will require
a Windows environment.


* Wine isn't portable enough.

I disagree here. I think this is bunk. It's been ported to a bunch of CPU
archs and operating systems. It's probably runs on only slightly fewer
platforms than Mono itself.


* Wines APIs are unstable.

See above. I think Peter is right, our exported APIs are not that large,
and making them stable is not that hard either. They don't even have to be
hard-iron set-in-stone will never ever ever change stable, simply doing
our best would be a big improvement over what we have now. The flip side
of this is that nobody is forcing you to use the latest version of Wine,
or even dynamically link to it in the first place, you could easily just
import snapshots into Mono CVS.


* People find it too hard to setup.

Well, I've been flicking through the June archives of mono-winforms-list
and I'm not seeing this at all ... yes there are lots of people saying "I
wrote this app and it doesn't work!" but then SWF isn't complete and
neither is Wine, so no big surprises there. The only setup related
problems I could see are related to hardcoded paths being compiled into
binaries - this is trivial to fix inside Wine and Mono, in fact I wrote a
patch months ago to do this for Wine (so it can run from any prefix). It'd
be easy to get this applied. The other problems I've seen are just random
crashes which could be in the SWF code or Wine, I don't know which.

Wine really is not hard to set up. You just install it, same as any
regular library. Yes, you can then not do mv /opt/wine1 /opt/wine2 and
have it run, but that's like a 10 minute fix as I already did 99% of the
work.


* GDI+/Wine interactions are too slow.

I suspect this isn't a problem for Microsoft because they implemented GDI+
in native code then bound it to .NET. You guys are trying to implement
GDI+ in .NET and then make Wine use it, which is a suboptimal solution.

I think if you had done it the way Microsoft did by writing a GDI+ DLL for
Wine and then mapped that to System.Drawing, there would not need to be
this constant mapping into System.Drawing contexs and things would go a
lot faster. Yes, that means implementing GDI+ in Win32/C, not much fun I
know, but it's the way Microsoft did it and therefore if we want
compatibility the way we must do it too (Wine will have to implement GDI+
itself at some point anyway).


* All our problems will go away if we implement S.W.F in C#

I strongly disagree with this notion. Nobody sane implements a
production widget toolkit unless they have to, they are HUGE, win32
especially so because it's so old. The listview control alone has a
bazillion different modes. I think Dimi estimated it'd cost $145,000 to
develop at current market rates. Even worse, you can't implement SWF is
managed code and get correct compatibility without reimplementing most of
Wine in managed code as well, which would be even sillier. 

The plan of doing an emulated WndProc in C# with the most common case is
just going to lead to an endless stream of people trying to run apps and
reporting "blah blah message isn't implemented", or worse "blah app has
native code and passes it Control.Handle". I'm very sceptical you can use
a "winelib plugin" to fix that - how can this work when the HWND the
native code is trying to use is fake? Oh, don't forget details like
handles being valid in any process! Programs that use
OLE embedding between themselves *depend* on that fact.

It especially makes me sad to see this because eventually people are going
to start coming to us with hybrid .NET/Win32 apps and want to run them via
Wine or Mono. They won't run on Mono because they'll P/Invoke to native
GUI code to do stuff that .NET/SWF can't do, and they won't run on Wine
because we don't implement the .NET framework.

I really think we should make another attempt to work together on this one
- last time Paul raised the issue of wine_init changing its prototype
(which caused them pain), Alexandre actually reverted the change. Too late
in some respects, the damage was already done, but I think it's wrong to
say we aren't interested in working with you. The last time Mono even had
a presence on this list, it was asking how to open Wine as a library and
example code was written for you. None of the other concerns were ever
raised here, as far as I remember.

Well, you seem to have made up your mind, but I just have this horrible
sinking feeling that one day WineHQ is going to have to do our own
implementation of S.W.F in order to be able to run apps of the complexity
people demand. Half baked solutions along the lines of "sorry using
Control.Handle/the registry/whatever isn't portable" won't cut it when
this is the last app blocking a migration to free software but they
can't/won't rewrite it.

ciao -mike




More information about the wine-devel mailing list