Running Visual FoxPro on Linux, Part 2

By Paul McNett (FoxTalk, August 2003)
Continuing where he left off in March, Paul McNett explores the nuances of using Visual FoxPro on Linux. Paul feels more freedom being able to work with VFP on alternative platforms, but there are lots of issues that you still need to know about before deciding to put your own applications on Linux.

After writing Part 1 of this series, I've spent some real time working with Visual FoxPro on Linux. I've successfully deployed an application to my Linux workstation, and maintained several other applications by using the VFP IDE under Linux. These efforts did have their struggles, however, and there are certain things I either couldn't do at all or that required significant workarounds.

This article will offer an overview of the current major trouble areas with running Visual FoxPro on Linux. After reading all of this, you may find yourself saying, "Boy, why would I want to go through all that hassle?" Indeed, this article is definitely a second act: It's about the sobering realizations of what works and what doesn't, and about looking forward to the climax of this saga—when the Wine project reaches maturity and Visual FoxPro looks and feels the same on Linux as it does on Windows. The pieces are all starting to fall into place, but as of this writing (June 2003) there are still some issues.

The Wine project, which makes it possible to run native Windows applications directly on Linux, is continually advancing. It's still Alpha software, which means it's definitely not ready for an end-user install, but as you saw if you followed my steps in Part 1, Visual FoxPro works surprisingly well on Linux. Since my article in March, a few fixes have been made to Wine that benefit Visual FoxPro. The patch that you had to apply to keep Visual FoxPro from freezing is no longer needed. Visual FoxPro windows can now be resized normally by grabbing the window border. WAIT WINDOW and ToolTipText windows are now displayed correctly (a patch is required for this, which I'll tell you how to apply). The GetFile() dialog box now displays correctly. The list of fixes and enhancements to the Wine project in general is quite large, and there are certainly other things that have made Visual FoxPro run better that I haven't even noticed yet.

Before I get much further with this, let me assure you that I fully expect Visual FoxPro to run perfectly well on Linux and Macintosh OSX within 18 months. As it stands currently, Visual FoxPro doesn't run at all on Macintosh OSX, and I estimate that it runs at about 75 to 80 percent of capacity on Linux. By getting your feet wet now, you'll be ready to develop and deploy on Linux and OSX when that time comes.

So, I'll start off by offering instructions on how to get current with Wine, which assumes you've read my original instructions in Part 1 (FoxTalk, March 2003). I'll then list some problem areas with Visual FoxPro on Wine, and offer workarounds or solutions where possible—should you want to get started sooner rather than later. By the time you read this, I expect that a number of current issues will already have been taken care of.

Getting current

Wine is being actively developed, fixed, and enhanced by hundreds of programmers worldwide. Dozens of patches get submitted each day, of which a few get committed to the source tree. Once or twice per month, the maintainer of Wine will make a new release, which is composed of the previous release plus the committed patches since then. In general, it's a very good idea to stay as current as possible with your Wine install. Don't depend on your Linux distribution to keep it current—Wine is typically months old even on RedHat (actually, last I checked RedHat doesn't even install it by default anymore). To get your Wine install current, please follow my instructions for installing Wine in Part 1, but get the latest version of Wine instead of the 20021219 version I specified—and don't apply the patch that I mentioned, as that patch has already been committed to the source tree. Make sure you follow the instructions in Part 1 to uninstall any previous instance of Wine, and if you're uninstalling the version you installed from my previous instructions, use the following commands:

cd ~/wine/wine
su
make uninstall
exit

Now, get the latest version of the Wine source (as of this writing, 20030508) and expand it into ~/wine/wine. Follow these steps to apply a patch to make the WAIT WINDOW and ToolTipText windows display properly:

1. Get the patch and save it to ~/wine/vfpwinepatchwinsize. I've included the patch file in the accompanying Download file, or you can download it from www.paulmcnett.com/vfp/wine/vfpwinepatchwinsize.

2. At the command shell, type the following commands:

cd ~/wine
cat vfpwinepatchwinsize | patch -p1

3. When asked for the file to patch, enter the following:

wine/dlls/x11drv/winpos.c

If all went well, you should have received a message that the patch was applied.

Okay, now you have the current source code and you've applied the latest patch to the source code, so you're ready to install. Follow my complete instructions in Part 1, but briefly what you need to do is:

cd ~/wine/wine
./tools/wineinstall

After the install finally finishes, do the simple tests to make sure it's all working, as outlined in Part 1.

Recap of critical Wine config file settings

The configuration file for Wine is located in your user directory, under the subdirectory called .wine. The file is named config. So, you can refer to this file as /home/<username>/.wine/config or as ~/.wine/config. There are a couple of critical setting changes you need to make to this file for Visual FoxPro and applications built with Visual FoxPro to run.

The most critical thing that you need to change is in the [Version] section of the config file. By default, Wine emulates Windows 95, and the config file shows the Windows version line commented out. You need to uncomment it, and change it to force Wine to emulate Windows NT4. (Note: Even for Visual FoxPro 8, which doesn't officially run on Windows NT4, you still want to set Wine to emulate NT4, as there are areas of VFP that don't work if you set it to "winxp" or "win2k".) You can make this change globally, as I just directed you to do, or you can put it in the application override section of the Wine config file as I directed you to do in Part 1. Once you have this fixed in the config file, Visual FoxPro will start without crashing.

You also need to make sure that you have the following Windows DLLs in your Wine fake Windows system directory (~/c/windows/system, if you followed my instructions):

• oleaut32.dll

• comdlg32.dll

• msvcr70.dll (VFP7 and VFP8 only)

• gdiplus.dll (VFP8 only)

msvcr70.dll and gdiplus.dll can be found on the VFP8 CD, while oleaut32.dll and comdlg32.dll will have to be copied from your real Windows distribution. (You've got a spare license for those files since you had to install Linux on a machine that originally came with Windows, since it's impossible to buy a desktop computer without Windows already installed.) Next, you need to edit the Wine config file so that the "native" versions of oleaut32.dll and comdlg32.dll are loaded instead of Wine's "built-in" versions, which can't at the moment seem to get the _VFP object properly set up, and can't display the MODIFY CLASS dialog correctly.

Before I go on, let me talk a bit about making the Linux command line easier to use. Your fake Windows directory has long directory names for certain directories, namely "Program Files". But because I use the command line for almost everything, I really hate having to type that in all the time. Do the following to make a shortcut:

cd ~/c
ln -s Program\ Files/ prg

You now have a symbolic link (a shortcut that Linux recognizes at the filesystem level) and can choose to type "prg" when you mean "Program Files". So, do this to start up VFP7, which you already did by following my instructions in Part 1:

cd ~/c/prg/vfp7
wine vfp7

The first thing you should do after VFP loads is to right-click on the command window and uncheck "dockable"—otherwise, strange things may occur (for what it's worth, strange things also occur on Windows with "dockable" checked).

Now, create a project, add programs, classes, and reports to it, build an executable, and just get a feel for the IDE in general. There are few areas that don't work, and the rest of this article is dedicated to discussion of the various issues I've encountered.

ActiveX controls

I have, unfortunately, been completely unable to get ActiveX functionality working at all. Adding ActiveX controls to your forms at design time doesn't work, because you didn't install VFP in the normal way, but instead just copied the VFP directory structure from your Windows computer to your Linux fake Windows directory. Some OCX files were missed, and some DLLs and OCX files were never registered. As of this writing, I'm still unable to install Visual FoxPro 7 or 8 from the installation CD—it complains that it can't copy files to my temp directory. If you want to figure out what files need to be copied and registered, I'm confident that everything would work fine for at least some of the controls. Note that Wine comes with its own version of regsvr32, and its interface is identical to that of Windows. To register comctl32.ocx, for example, type the following:

cd ~/c/windows/system
regsvr32 comctl32.ocx

You'll now see the common controls in VFP's tools/options/controls/ActiveX section. However, if you try to use them by putting a TreeView, for example, on a form in the class designer, you'll get an error that the appropriate design-time license isn't found. To get this to work, you need to locate the appropriate Registry keys on your Windows install, export them to a .reg file, and copy them over to your Linux/Wine file system and import them. But even this may not work, as I tried registering comctl32.ocx on my machine and running a VFP app that had been compiled in Windows with a TreeView control, and I couldn't get the TreeView to work at all on Linux. So, for now at least, consider ActiveX controls as out of bounds for Linux/VFP apps. I've always pretty much avoided ActiveX controls in my apps anyway, usually electing to make my own controls based on Visual FoxPro's native controls, so this really isn't an issue for me. But do take heart: ActiveX will eventually work in VFP/Wine, it's just a matter of time.

Declare DLL

Now for some good news: Declaring functions in external DLLs—including the Windows API—works just fine as far as I can see. This makes sense when you think about it, because applications rely on the Windows API for almost everything they do. Most of the commonly used API functions are already implemented in Wine, and if they aren't you can usually just tell Wine to use a native copy of the DLL in question by editing your ~/.wine/config file and specifying that it try to use the native version first (you'll have to copy the native DLL from your Windows installation). Most third-party DLLs should work just fine in this manner as well (copy the DLLs to your application directory or to the ~/c/windows/system directory, whatever you like—Wine and Visual FoxPro will find them and integrate with them just fine). I've tested various functions in the WinAPI, and various third-party DLLs, and had no issues at all.

Record locking

In all versions of Wine prior to wine-20030318, record locking didn't work. But it works now—get the most recent version of Wine to make sure record locking is enabled. This is great news—I originally had a few paragraphs written with suggestions for workarounds and a prediction that record locking would be working within 18 months. I'm overjoyed to be incorrect, and to have to cut those paragraphs!

That said, there's a newly discovered bug that will cause record locking to not work correctly in certain situations. The bug isn't with Wine, but with the Linux implementation of smbmount, which is essentially the client side of the Windows file sharing mechanism. The short answer is that connecting your Linux box to a file server by using the smb client will result in incorrect locking. This is unfortunate because it's a common situation to have your DBFs on a Windows server for all your clients (Windows and Linux) to connect to.

The answer is to not connect to your data from Linux using the smb client, at least for now. What I'd suggest instead is that you move your data over to a Linux Samba server and connect with Microsoft Networking from your Windows clients, and that your Linux clients use the native NFS (Network File System) to access the data. You'll likely find that Linux is a much better file server than Windows anyway (I put a Linux Samba server at a client almost two years ago and all data problems have gone away—and they've never had to reboot that server). By connecting with NFS from Linux, and with SMB from Windows, locking is respected by all. Configuring Samba and NFS is beyond the scope of this article, but it isn't hard to do.

Fonts

Visual FoxPro, along with other Windows applications, typically expects certain TrueType fonts to be available on the system, and Windows fonts are certainly much nicer than most fonts you'll find in the Linux world, at least so far. The good news is that it's very easy to install the package of Microsoft fonts onto your Linux machine, and those fonts can then be used by all your Linux applications, not just Wine. Fonts such as Times New Roman, Arial, Courier New, Andale Mono (my personal favorite for the VFP code editor), and Verdana can all be installed by following the instructions at http://corefonts.sourceforge.net (just follow the instructions under the "How To Install" section, and you'll be fine). Do this once, and the next time you start Wine you'll have to wait a few minutes for some FontMetrics to be configured, and from then on you'll have all the standard Windows fonts available.

So that's the good news. The not-so-good news is that the various font-properties windows in Visual FoxPro don't work correctly. You may choose Arial, size 12, bold, but you actually get Arial, size 10, italic. Note that I'm talking here about the font-picker window that you see in the report designer, for instance. Font properties as set in the Properties sheet of the form/class designer work just fine. I've been able to use trial and error to get the actual size I desire, but it's definitely annoying nonetheless.

Weird window backgrounding

You've likely encountered this issue already, and I touched on it in Part 1 as well. As you type in the command window (or right-click with the mouse, or choose to look at the Classes tab in the Project Manager, or in umpteen other places), the main VFP window may disappear, leaving you with only the foreground pop-up window visible. From then on, until you switch back to VFP, the VFP window will still have the focus but it won't be visible to you. Actually, it's visible but merely behind all other open windows. This is an annoying problem, but there are a few workable options.

Your Linux X Windowing environment has any number of virtual desktops that you can use. Look down in your Linux taskbar and there's likely a representation of four possible virtual desktops. You can choose to put VFP on its own virtual desktop, and then, since it's the only application on that desktop, it will never "disappear." To do this, select the control menu (upper-left of the VFP window) and choose "To Desktop..." and select an empty desktop. Then switch to that desktop by clicking its representation in the taskbar and you're all set.

That solution is what I did for a while, but I got really tired of switching to different desktops, especially with several instances of VFP running alongside several instances of the various VFP-built applications that I was testing. Instead, I've set a configuration option to not let X Windows manage my VFP windows. This means that your VFP windows won't appear in the Linux taskbar, nor will you be able to Alt+Tab between them. They'll be AlwaysOnTop, which means you're forced to minimize them when you want to switch to another app. I still like this better than the first option, but it sure is inconvenient to be forced to minimize the window and then search for the icon floating on the desktop to restore it. To try this option out, look for the line in ~/.wine/config under the [x11drv] section that looks like "Managed" = "Y". Take the semicolon away from the beginning of the line, change the "Y" to "N", and restart Wine/VFP (exit VFP and restart VFP). As long as no other instances of Wine are running, your new settings will take effect.

There's an additional option: Under that same [x11drv] section in your ~/.wine/config file, set the following:

; Allow the window manager to manage created windows
"Managed" = "Y"
; Use a desktop window of 800x600 for Wine
"Desktop" = "800x600"

With these settings, Wine will put your VFP window inside a container window of size 800x600. You can't size the container window at runtime, but you can resize your VFP window within it as you see fit (I don't see any point in doing anything but maximizing it). Each instance of VFP you run will result in a separate Wine container window. This looks kind of hokey, but it's the best of all the options in my opinion because you can still Alt+Tab between applications.

Now for the great news: The Wine developers rewrote some of the windowing modules, and my testing today indicates that this "weird window backgrounding" problem was fixed with the rewrite. Therefore, the next version of Wine (the version that will come out after wine-20030508) will be the version that you want to use, and if you do you won't have to worry about this issue at all.

The class designer

Dock your properties window, float your form controls toolbar, double-click to edit the code, Ctrl+F to find code—everything seems to work just fine in the class designer and form designer. Well, except for one annoying bug: You can't copy/paste objects. I didn't realize how much I rely on setting up an object on a form and then copying and pasting it to other places on the form (OOP purists might cringe, but setting up a label class with right-alignment and a width of 84 just for the purpose of putting it on this one form is more work than I want to do). This is interesting, because copying/pasting of things in other places works just fine (the report designer, for example). Anyway, I've worked with a lot of classes and classlibs on VFP/Linux, and the copy/paste problem is the only issue I've discovered.

HTML Help

Because of all the interdependencies with Internet Explorer, HTML Help won't work. The folks at Wine are working on an HTML Help viewer, but it will probably be a while before that becomes available. This situation makes it a bit difficult to develop on VFP/Linux, because the Help file isn't there at the ready for me when I need to look something up. But, that's one of the reasons I keep Windows around on my VMware virtual PC running on my Linux box. When I need to access foxhelp.chm or hackfox.chm, I just switch over to my Windows virtual PC, and look at the Help file there.

There has been some talk of people being able to get Internet Explorer running under Wine, but it looks pretty hairy and there are all kinds of warnings about possible file corruption issues. Perhaps if you could get Internet Explorer working, you could then get hh.exe working and be able to view CHM Help files. I didn't try that, opting instead to wait until there's a Wine HTML Help viewer available.

The report writer and the report designer

I've had a couple of instances in the report designer where VFP has frozen or generated a C0000005 error—I don't think that this is necessarily a problem with Wine or Linux, but more likely a problem with the VFP code itself, as I've gotten C0000005 errors with the report designer on Windows as well. Actually, the report designer and report writer both work as well as they do on Windows, with one exception. Printing support is very primitive so far in Wine, and difficult to set up. This is indeed a showstopper for application deployment, but not necessarily for application development and testing. A good deal of the development work occurring in Wine has to do with printer setup, so it's only a matter of time before it all works (for example, someone is working on a "printers" control panel applet just like you have in Windows).

Because of the current printer setup difficulties, you probably won't be able to edit printer properties settings such as landscape/portrait. In fact, unless you can set up a printer at all, the GetPrinter() dialog is empty, and prone to causing C0000005 errors. So developing plain-vanilla portrait reports can be done with ease, but you won't be able to design a report with any of the printer driver-specific options such as landscape, duplex, or custom sizes and tray assignments. I'd recommend using VFP on Windows for working with reports, for the time being.

Connecting to remote data with ODBC

Here's an area that works extremely well. The key is to use the Windows-native ODBC32.DLL driver. I connect to back-end MySQL servers using the MyODBC 2.5x driver, available from www.mysql.com. This driver's setup file will run fine under Wine, as long as you have "Windows" = "nt40" in your Wine config file. It will install the Microsoft ODBC driver (circa 1995) and the MySQL driver. From there, it's all the same as far as VFP is concerned. I did have trouble using connect strings with SQLSTRINGCONNECT(), but had no problem setting up a user DSN and connecting via SQLCONNECT().

Wine does come with its own implementation of ODBC, which looks really slick as it wraps around the Linux-native UnixODBC package. For some reason, even though I can set up my UnixODBC connections and test them from the Linux command line successfully, Visual FoxPro fails with stack overflow errors when I try to use SQLCONNECT() or SQLSTRINGCONNECT() on them. So set your ODBC32.DLL to "native" in your Wine config file and you should be all set. Do install MyODBC 2.5x from MySQL, even if you don't use MySQL, as it will set up the Microsoft ODBC programs and Registry entries, and you can then do a "wine odbcad32.exe" to set up your DSNs.

CursorToXML() and XMLToCursor()

CursorToXML() works, while XMLToCursor doesn't. This is because the first is implemented entirely in VFP, while the latter is implemented in the MSXML system DLL.

Making a _WINE public variable

Remember the _MAC and _UNIX system variables that you could use to conditionally branch your code to handle idiosyncrasies among multi-platform applications? While I haven't found the need for it yet in my code, I thought it would be a good idea to define a new public variable—both in my IDE sessions as well as in my deployed applications—so that no matter where I am in the code, I know whether I'm running under Wine or not. This is easily handled by checking for an environmental variable called "_". Under Windows, it probably doesn't even exist, but under Wine it will contain a string such as "/usr/local/bin/wine". So, put code such as the following in your top-level startup program:

PUBLIC _WINE
_WINE = "wine" $ LOWER(getenv("_"))

Wine will pass all Linux environmental variables into the Wine environment, making them accessible from VFP with GETENV(), and the underscore is an automatic environmental variable in Linux—it contains the last-executed script or program run from within that shell. I took advantage of that fact in crafting the _WINE public variable.

Macintosh support

As of this writing, Wine will compile on Mac OSX, but it won't run without crashing. This is a better situation than just two months ago, when Wine wouldn't even compile. This is thanks to a new open-source project called DarWine that has forked the Wine source code with the express purpose of getting it to compile and run on a Mac. Once this happens, OSX users should be able to use DarWine, coupled with Apple's recently announced X11 package, to get Visual FoxPro running directly on a Macintosh. Stay tuned on this one... Imagine having the flexibility to deploy your VFP apps to three platforms again!

VFP8

Most of my detailed testing so far has been with VFP6 and VFP7. However, I've had the opportunity in the past couple months to move one of my VFP7 applications over to VFP8, and to make an entirely new application in VFP8. While both of these applications get deployed to standard Windows workstations, I used my Linux/Wine VFP8 IDE to do most of the developing.

The good news is that for the most part, all of the features that were part of VFP7 will work in VFP8 under Wine. The bad (but not unexpected) news is that most of the VFP8 enhancements have trouble in Wine. For instance, don't even try running the Task Pane, as it relies heavily on Internet Explorer. Similarly, the Toolbox and Find References have problems because of missing OCXs. Basically, the things that work in VFP tend to be the things that are built into the VFP executable or runtime libraries. The things that don't work tend to include system libraries, which are likely not set up on Wine because you didn't actually install VFP—you just copied it over. VFP8 includes more of the latter type of feature, and therefore very few of the IDE enhancements work on Wine at the time of this writing.

However, language enhancements such as TRY...FINALLY, CursorAdaptor, and the Empty Class seem to work just fine. The report designer improvements, such as tabbing between controls and Page X of Y, work. The "View Parent Code" button functions as advertised.

One thing that doesn't work properly in VFP8, even though it used to work in VFP7 and before, is the adding of resources to your EXE file during the build process. One of the last things that happens to your EXE when it's being built is the addition of version resources and icon resources. In VFP8, these resources don't get added.

In conclusion

In short, today's Wine is capable of running basic, plain-vanilla setups of the VFP IDE and VFP-generated apps on Linux. Over the next 18-24 months, however, Wine will be moving out of its current Alpha stage of development into Beta and finally Version 1, and we can expect that most features of VFP will run reliably and consistently across platforms.

Linux and Macintosh both represent growth markets for desktop applications. There currently are no IDEs for developing database-centric applications (what other types of applications are there, really?) with VFP's richness available for either platform. Opportunities are ripe for growing the popularity (and sales figures) of the Visual FoxPro product, by making and deploying Visual FoxPro applications on Linux and Macintosh, as well as on traditional Windows. Instead of being in a dying niche, Visual FoxPro developers can be in high demand again!

© 2003 Paul McNett