Thursday, January 26, 2012

Firefox - session file invalid error...

I ran into an issue with Firefox today, and after scouring the web without finding an answer and plowing through the sessionstore.bak file to try to fix it, I finally figured out the issue.

In Firefox 9, the Tools->WebDeveloper->Error Console had the following error:

session file is invalid type error this_initialState.window[0] is undefined

This occurred after FF crashed and I had to kill it - even reboot - and such as it the whole system was bogged down by something. I couldn't find anything on-line about it and started digging in. Firefox would not restore my session - all the tabs and tab groups, etc.

I did a comparison with the new sessionstore.js file that it had, and found that there was a little section that was missing from the default, but present in the backup - in bold below:


{
"windows":[],"selectedWindow":0,"_closedWindows":[{"tabs":[{"entries":[


I removed the text, copied the resulting sessionstore file over sessionstore.js, and viola - firefox reloaded everything!

Hopefully others that have this issue will find this post and not have to spend a couple hours trying to figure out how to get their data back.

Friday, January 20, 2012

What the content industry doesn't get about SOPA/PIPA

Lamar Smith recently wrote an article for CNN concerning SOPA. However, he doesn't get what is wrong with it, straight from the opening paragraph:

The growing number of foreign websites that offer counterfeit or stolen goods continues to threaten American technology, products and jobs. Illegal counterfeiting and piracy costs the U.S. economy $100 billion and thousands of jobs every year. Congress cannot stand by and do nothing while some of America's most profitable and productive industries are under attack.

Okay, foreign counterfeiting and stolen goods are bad things. However, there is nothing showing that they cost jobs or billions of dollars. Many properly done studies show that piracy of this manner usually helps drive business to the original creator.

For example, someone making a counterfeit handbag won't have the quality of the original. Someone may buy it, but it'll break down, and they'll probably replace it with something from the original - especially if they were in a first-world country (e.g. US, Europe, Japan, and Australia) than to go and get another counterfeit.

Or, take music. The Grateful Dead and They Might Be Giants have both had a long history of encouraging people to copy and use their works. Both are extremely large bands now with very large and loyal audiences. This has not hurt them at all, but rather it drives their sales - as people hear the music and buy more from it when they discovery they like it.

Or take movies. The Anime community has a long history of importing works and dubbing (called Fan Dubs) or subbing (called Fan Subs). As a community they also encourage people to buy the licensed work when it is finally imported and subbed or dubbed for the country. This only introduces the works to bigger audiences, finds new audiences, and builds additional customers. Yes, there are some fans that just won't go the legal route, but most will.

In all cases, that $0.30 lost on one produce to piracy might turn into $5 or $6 down the road in repeat business.

But let's get back to SOPA/PIPA.

The Stop Online Piracy Act protects consumers and innovators by targeting foreign websites that traffic in stolen or counterfeit products, everything from movies to medicine to baby food.

Again, it's a good thing to stop counterfeit products that hurt people - medicine, baby food, etc. But this isn't being targeted at those kinds of things. It's being targeted at copyright infringement, and bypasses Due Process.

That is, it only takes one entity to show up in court and accuse a site (any site) of infringing their copyrights, and the court would be obliged to grant a takeover of the site. The owner isn't necessarily notified until their customers complaint that site is off-line, unless their DNS Registration provider (e.g. GoDaddy, etc.) notifies them as they move the DNS to pointing elsewhere.

This flies in the face of the U.S. Constitution which has a Due Process Clause - mentioned in multiple places: 5th Amendment and the 14th amendment.

The major backers of SOPA/PIPA - namely the Content industry (MPAA, RIAA, TimeWarner, NBC Universal, Disney, etc.) after having to go through Due Process for years and then losing in court for not being able to name the infringers - or having to show why they should be able to get those names and sue them to start with - is tired of Due Process, so they could really care less about it at the moment. (Though they probably will regret that should SOPA/PIPA ever pass.)

This information does a disservice to consumers, and it is being disseminated by those who have profited from working with illegal websites that steal and sell America's intellectual property.

There is a lot of dis-information yes; and it is being propagated primarily by the backers of SOPA/PIPA. Those against it are point out its actual results. The recent Internet Blackout day shows exactly what will happen should SOPA/PIPA pass. Google and others have a very good right to fear SOPA/PIPA and not because they profit from it. (BTW, I am speaking out against it and showing the problems with it too, but I do not profit from any infringing activities as Lamar claims I might since I am against it.)

The reality is that SOPA/PIPA have a very big legal affect that will severely hamper the creativity of the markets, especially on the Internet.

For instance, I am getting read to start a company. I have a product planned that I am going to make, and I'll have a website. However, if another company complains that I am infringing their copyright - without even showing it, just making an accusation - they could shutdown my start-up's Internet site, and effectively close up shop for the company. All because of an accusation by some entity that doesn't like what my company is providing, and would rather sue and shut me down than innovate themselves.

The online blackout that occurred this week, which included Wikipedia, was also misleading. Wikipedia has nothing to fear from SOPA. It is ironic that a website dedicated to providing information knowingly offered misinformation about the bill. SOPA will not harm Wikipedia, domestic blogs or social networking sites.

Wikipedia has everything to fear as all that needs to happen is for someone to upload some content that someone else claims infringes their copyright and ALL of Wikipedia gets shutdown.
So again, Lamar is providing dis-information.

Hyperbole has been rampant in the debate about SOPA. However, the bill in no way censors the Internet. It only targets activity that is already illegal, and only targets foreign websites that are dedicated to illegal or infringing activity. In fact, it is similar to laws that already govern websites based in the U.S.

Censorship automatically occurs when you start shutting down websites based on accusations. It would be one thing if the site and its owner had gone through the courts and were found completely guilty. However, the content providers don't like (i) how much effort it takes for them to do that, (ii) their likelihood of success that way, or (iii) the time it takes. However those three things are there to protect the whole of society from the 'mob', to ensure the rights under the law of all involved. SOPA/PIPA are 100% against that - a direct reflection of their supporters who probably had a very big hand in drawing the bill.

What has not been publicized is the broad support for SOPA. It has been endorsed by a diverse group of organizations, including the National Association of Manufacturers, International Union of Police Associations, the U.S. Conference of Mayors, the National Songwriters Association and the National Center for Victims of Crime. The bill has even united strange bedfellows: the U.S. Chamber of Commerce and the AFL-CIO. It's not every day that you see business and labor on the same side of an issue.

This just goes to show you that the organizations that support it have a big hand in commerce and not much in the way of protecting citizens. National Songwriters Association is part of the RIAA. RIAA and MPAA also have strong ties to the U.S. Chamber of Commerce and AFL-CIO; several of the companies therein (Time Warner, etc.) also have ties to device manufacturers through their DVD/BlueRay businesses. They also have a strong hand politically generating lots of money into politics. So again, the above are not surprising to see.

Even the White House has weighed in, endorsing the need for legislation

And the current administration at the White House has very strong ties to Hollywood. So again, it would only be surprising if they were against SOPA/PIPA. Same for any democratic organization (e.g. Unions) - and unions tend to back each other. So the Actors Guild would probably support things by the Police Union, and vice versa - the whole "I'll scratch your back if you scratch mine" thing (e.g. Old boy's network) as two appear strong than one.

respect the First Amendment and believe that any legislation passed by Congress must protect and defend our constitutional rights. But illegal and criminal activity is not protected by the First Amendment simply because it takes place online. For example, there is no First Amendment right to view, distribute or download child pornography over the Internet. Like child pornography, the theft of intellectual property is also illegal in the United States.

The major issue is not the First Amendment. It's the Fifth and Fourteenth Amendments - the right to Due Process.

The Stop Online Piracy Act works by cutting off the money to foreign illegal sites and making it harder for online criminals to market and distribute illegal products to U.S. consumers. The bill includes provisions that "follow the money" to cut off the main sources of revenue to these sites, and also protects consumers from being directed to foreign illegal websites by search engines. And it provides innovators with a way to bring claims against foreign illegal sites that steal and sell their technology, inventions and products.

But you wont' just get foreign sites. You'll get backlash that will involve domestic sites as well. And why would they stop with foreign sites? They'll do their best to show that a domestic site has foreign ties and therefore should be shutdown just the same - and they'll probably do it by just showing that the site does business internationally (which ALL Internet sites do by default).

Unfortunately, some critics simply want to maintain the status quo that harms U.S. companies, consumers and innovators.

Actually, I don't like the Status Quo either. We started down an ugly road back in 1998 with the DMCA - something that needs to be repealed at least in part.

I also believe current laws provide us all the tools necessary to combat piracy and counterfeiting without the need for SOPA/PIPA or even the ACTA Treaty that has been worked on in secret.

Wednesday, January 04, 2012

Iowa Primaries...

Well, congratulations to Santorum on doing so well in the Iowa primaries. I hope the momentum continues and that you get the nomination.

Please consider one thing - making Newt Gingrich your VP. The two of you would make a great pair for the main race.

Sunday, September 18, 2011

Qt5 - Introducing QDaemonApplication

Okay, so I'm not quite done with QDaemonApplication to the point where it's even testable yet. However, I wanted to at least announce it to get feedback on the structure I am using. Questions are good, and it'll help it be more robust in the end.

Also, I'd like to note that I'm not quite use to PIMPL so if there's something I did wrong in that respect, please let me know so I can correct it. I also use a slightly different programming style; however, I tried to keep it similar to what I am finding in other areas of Qt for consistency. Please let me know if there is anything inconsistent in that respect too.

So with that said...

I originally wrote about the effort in a previous blog post (see Calling Contributors and Qt5 & a major update for QtService - QDaemonApplication), and I finally found some time to be able to work on it, still with the goal to get it in intime for Qt5.

As a user of Qt5, a programmer would simply use the QDaemonApplication class much like the presently do for the QCoreApplication or QApplication classes. Though it they will also be able to do some more things between instantiating the QDaemonApplication and calling its exec() function - check parameters, etc - potentially even fully by-passing the exec() if they chose (of course, then they won't get a daemonized application, and the main program won't run - but that can be useful in certain scenarios).

Behind QDaemonApplication is a series of APIs that provide the functionality. These APIs start off with some very basic Interface classes (QAbstractDaemon*) for the Interface (e.g. command-line, systemd, Win32 SCM, etc.), Communication between the Interface program and the daemonized program, and platform integration (e.g. Win32 SCM). This structure will allow us to easily switch between different components to do different tasks - e.g. Win32 SCM vs LaunchPad vs SysV vs systemd vs upstart - and communicate in different ways - e.g. Win32 SCM, File Pipe, Network Socket, etc.

Eventually as we add more, and support more, then the interfaces, etc will be chosen when Qt5 is built, and we'll try to keep sane defaults; however, presently I am simply trying to replicate the same level of functionality that is in the existing Qt4 QtService Add-on component.

So, if you're interested in looking at what's there, even though the code documentation is thus far pretty much non-existent, you can see it at BRM-Qt5-Service on Gitorious.

Tuesday, June 21, 2011

Qt5 & a major update for QtService - QDaemonApplication

In May I proposed that QtService be integrated natively into Qt5 [1], and I offered to spearhead that task [6] and support Windows and Linux (Embedded and X11)[6]. In June I setup a branch of the Qt5 master repository[10] for supporting this task (I'll likely need to rebase it), and am working to get up to speed on using git (I have primarily used SVN), so I expect that getting going will be a little slow in that respect. (Sadly, a bit slower than anticipated. I am working on it.)

All that said, below is the summary from the Qt5-Feedback mailing list covering naming conversations, etc; and some additional stuff as I have contemplated that. The discussion has been very good thus far, but has made keeping track of via e-mail a little hard – so I am looking for a nice Wiki home for it all. I'll put it there once I find a nice home (probably at the Qt Dev Wikis somewhere) and get a chance to repost it here.

In the mean-time, please feel free to leave comments below.

Background:

QtService is presently an add-on provided by Trolltech/Nokia through the Qt Components system [1]. However, for a variety of reasons it is desirable by myself and others that it be a native part of Qt [1,3] whether as part of Qt Core or a module provided with Qt itself [1, 9]. In either case, it needs some TLC to bring it up to date as well as some improvements. To start, the existing QtService implementation is a C++ Template-based implementation[1,3]; the end result is that this prohibits use of signals/slots internally to the QtService code [1,3], prevents the ability to do a scheduled, orderly shutdown [1], and makes it hard to work with the command-line [3,5].

It has been proposed to make a new QtService implementation that makes use of C++ Abstract Interface classes instead [1,3]. In the process of doing so the ability to derive an interactive service will be removed per encouraging best practices and that it will not work on all platforms [1,3]. The new implementation should likely use a different name - e.g. QService, QDaemon, or QDaemonService - to be more consistent with existing names of parallel functionality - e.g. QCoreApplication, QApplication [5], and should address issues in the command-line [3,5], communication between controller and service [5], and add the ability to do controller shutdowns of the service [1].

Location:

I originally called for the work to be integrated into Qt Core.[11] However, after fleshing out further details we revealed several dependencies on modules – Qt SWF, Qt Network, and others. That is not to say that Qt SFW and this may not end up in the same module, but it will at least be in a separate module. For the time being, I am calling the new module QtService with the intention that Qt SFW be able to share it (more below).

Naming:

I originally proposed to use the name QDaemonService.[11] Some thought this was too long and it was proposed to just use QService.[14] However, it was pointed out the Qt SFW already uses this QService* namespace.[20,22] So, we will use the QDaemon* namespace instead to minimize confusion in the API.

Interface:

QDaemonApplication will be a formal object like QApplication and QCoreApplication, and should set up the application environment in a similar manner. That is, the command-line options provided should be available via calling QCoreApplication::arguments(). It should also have a function to tell the program whether it is the formal service or the controller so that developers can interact in both modes - thus being able to interact with the command-line as necessary.

In keeping with the naming conversions mentioned previously [5,11] the primary interface class with be QDaemonApplication. Thus the main application will look something like the following:


    #include

    int main(int argc, char* argv[]) {
        QDaemonApplication service(argc,argv);
        ...
        return service.exec();
    }


Back-End Communications:

In the QtService component, the service code used network connections under *nix and the Win32 Service Manager API on Windows for communication, which primarily relies on some IPC and command-line stuff to communicate. I think it is very important that each platform integrate something native to do the communications. To that end, I believe Qt SFW likely provides the best method of providing that functionality, and think we should collaborate between the two to utilize the IPC portion. Windows support will still require using the Win32 Service Manager API at least on the front end, and may in the back-end too so there may be some additional options of that nature. But primarily, I think we can rely on Qt SFW for IPC functionality – to provide integration for IPC, D-Bus, Shared Memory, etc – whatever is best for the platform and do so via a configurability during compile or (even better) at run-time. Otherwise, I fear we may reinvent the wheel that another portion of Qt has already finished – so why do it twice when the functionality is already there? (Yes, I realize Qt SFW was not available in Qt4 so readily. But from what I understand it will be in Qt5.)

This functionality will be hidden by the QDaemonApplication class. Developers utilizing these classes should not have to be concerned about the back-end communications – it should just work from their perspective.

Front-End Interfaces:

In the QtService component, the service code used the command-line as the sole front-end interface. However, QDaemon* should integrate with various systems, as well as keeping that simplistic command-line interface. So, while the command-line interface will be the first-out-of-the-gate supported front end, we should also add configuration support (likely build-time only) for supporting other mechanisms – e.g. systemd, zeroconf, upstart, bonjour, launchpad, etc. Once we have moved beyond supporting solely the command-line then native mechanisms will be set to be the defaults for each platform when such functionality is available (e.g. launchpad on Mac). In the case where there may be several different mechanisms (e.g. Linux – systemd, zeroconf, command-line, D-Bus, etc.) then we may select an appropriate default – e.g. D-Bus or command-line for Linux.

The primary idea here is that since there are so many different front-ends for driving service/daemon applications, it should be configurable with appropriate defaults selected. It should be as easy as possible to enable integration of new front-end interfaces for future expansion.

This functionality will be hidden by the QDaemonApplication class.

Developer Interaction:

As the application will daemonize itself in the QDaemonApplication object, developers will need to have an interface object with that class. To this extent, Developers will be required to create a class derived from an abstract interface class – QAbstractDaemonObject – which is then registered in some manner (function/signal/slot) with the primary QDaemonApplication object.

Class Architecture:

The QDaemon* namespace will consist of two public classes:

QDaemonApplication
QAbstractDaemonObject

And a number of internal classes to provide the various mechanisms for setting up the environment, interacting with the front-end APIs, etc.

The primary purpose of QAbstractDaemonObject will be to provide sufficient interfaces for developers to utilize both pre-demonization and post-daemonization. The QDaemonApplication object will do most of the work in bringing up the application, however, it will not daemonize the application until the exec() function is called – thus providing the developer time to interact with the pre-daemonized process. By allowing the developer to derive from this interface, we can also provide sufficient means to enable communications for the developer between the pre-daemonized and post-daemonized process – for custom communications (likely serializing to and deserializing from a QByteArray) via standardized signals/slots.

Instances:

Some platforms (e.g. Windows) only allow a single instance (primarily determined by the installation location and name of the service as registered with the Win32 Service Manager API) of a service to operate at a time. Other platforms could care less. To this degree, QDaemonApplication should contain the ability to differentiate between platforms and inform the developer if it is allowed, and if it is provide the developer with an easy means (boolean option) on whether to allow it or not.[14]

I think that's enough to get some discussion going.

[1] http://lists.qt.nokia.com/pipermail/qt5-feedback/2011-May/000246.html
[2] http://lists.qt.nokia.com/pipermail/qt5-feedback/2011-May/000247.html
[3] http://lists.qt.nokia.com/pipermail/qt5-feedback/2011-May/000253.html
[4] http://lists.qt.nokia.com/pipermail/qt5-feedback/2011-May/000256.html
[5] http://lists.qt.nokia.com/pipermail/qt5-feedback/2011-May/000259.html
[6] http://lists.qt.nokia.com/pipermail/qt5-feedback/2011-May/000262.html
[7] http://lists.qt.nokia.com/pipermail/qt5-feedback/2011-May/000266.html
[8] http://lists.qt.nokia.com/pipermail/qt5-feedback/2011-May/000267.html
[9] http://lists.qt.nokia.com/pipermail/qt5-feedback/2011-May/000264.html
[10] https://gitorious.org/~benjamenmeyer/qt/brm-qt5-service
[11] http://lists.qt.nokia.com/pipermail/qt5-feedback/2011-June/000449.html
[12] http://lists.qt.nokia.com/pipermail/qt5-feedback/2011-June/000450.html
[13] http://lists.qt.nokia.com/pipermail/qt5-feedback/2011-June/000453.html
[14] http://lists.qt.nokia.com/pipermail/qt5-feedback/2011-June/000454.html
[15] http://lists.qt.nokia.com/pipermail/qt5-feedback/2011-June/000455.html
[16] http://lists.qt.nokia.com/pipermail/qt5-feedback/2011-June/000457.html
[17] http://lists.qt.nokia.com/pipermail/qt5-feedback/2011-June/000459.html
[18] http://lists.qt.nokia.com/pipermail/qt5-feedback/2011-June/000460.html
[19] http://lists.qt.nokia.com/pipermail/qt5-feedback/2011-June/000461.html
[20] http://lists.qt.nokia.com/pipermail/qt5-feedback/2011-June/000463.html
[21] http://lists.qt.nokia.com/pipermail/qt5-feedback/2011-June/000478.html
[22] http://lists.qt.nokia.com/pipermail/qt5-feedback/2011-June/000500.html
[23] http://lists.qt.nokia.com/pipermail/qt5-feedback/2011-June/000525.html

Friday, May 20, 2011

Calling contributors...

Recently Nokia announced the initial planning stages for Qt5, and looked to the community for ideas on how to improve Qt in a generally source-compatible way, meanwhile allowing extensions to be added and some things to be modified. All this, via the a mailing list - qt5 dash feedback at qt dot nokia dot com. There have been a number of great ideas that have come up - from additions to the QDateTime, time-zone support, enhancing the printing, integrating more from KDE, and lots more.

So why this blog? Well, I've been working with Qt professionally for just over 2 years now making a distributed network-based geometry measurement system for the railroad industry. The design uses a lot of service applications - which, use the QtService component add-on. Well, I'd very much like to see the QtService component become part of the Qt Core library in Qt5, but it needs a bit of love to get there.

Don't get me wrong - QtService is great. It works wonderfully, but it hasn't been updated in quite a while, and doesn't officially support Qt 4.6 or 4.7. Looking at Gitoroius, it's been put into the archives - i.e. its no longer going to be officially supported. Yet, I use this every day and I'm sure others do as well.

There are also a few other relatively minor problems with QtService:

1. It is template based. And this means that the base application from which you derive your own application can't use Qt's signals/slots to deliver the basic functionality. This is of greatest hindrance in the communications between the 'controller' portion of the application (which is provided for you) and your application. It also makes it very difficult to do things like delaying a service stop request (e.g. so you can unregister the application from a central server).

2. The command line is rather limited. That is, you get what they provide you and its very difficult (actually nearly impossible) to extend it to do other things - especially if those things are passing a parameter to your application (since there is NO signal you can send to it).

So, here I am now looking ahead to Qt5 and seeing that this nice component is not going to be supported. Meaning, I'm going to have to support it myself - and so is anyone else that wants to use it too, and I'm sure there are others out there.

Of course, since it is not a first-class citizen to the Qt Framework - and you have to explicitly pull it in and install it - then I'm sure that not everyone that really could make use of it does. So there are probably a lot more people out there that could make use of it and aren't simply because its too much work to install and use it, and you get those icky limitations that aren't very friendly to you either.

Fortunately, Qt is open source. And Nokia is moving Qt to open governance, especially with Qt5. This means that I, and everyone else, have the ability to contribute to Qt5 like never before. It also means if we can get a suitable new replacement for QtService written and on par with other parts of Qt then we stand a chance of having it become part of Qt itself - a first class citizen.

Well, time to wrap up my thoughts for this post...essentially, I have now joined gitorious (https://gitorious.org/~benjamenmeyer) and will be making a branch in the next week or so to star this work on. (Very exciting). Yes, I plan to "put my money where my mouth is" or so the old saying goes. I doubt my employer will let me do it on company time, but it'll be worth it if only so I don't have to maintain the other version in a lot less friendly and open manner. (Of course, that also means pushing my employer to use Qt5 when the time comes, which is quite a bit easier to do.)

So once I get back home, then I'll be finishing the setup of my gitorious account, and creating a branch, and possibly a team, for this effort. I very much do look forward to learning git in the process (I've been a staunch SVN user for years, but I mostly do work where centralized versioning makes sense; and community projects like this make better sense with a distributed versioning system.)

So, anyone else out there that is using QtService component, or would like to join in - please join us on the Qt5 Feedback mailing list mentioned above, and we'll get you plugged into the new work once I get it all setup.

And certainly look for more here as this endeavor continues. I'll certainly try to post more as it comes together.

Thursday, February 10, 2011

Portable software...

Over the last year and a half I've had the opportunity to work with Qt in software development, and I've enjoyed it greatly.

In a previous job, I looked at what it would take to port our software from being just on Microsoft Windows to also running on Linux, Mac, and various UNIX operating systems. In the course of that research I looked at several options: (i) Qt, (ii) Gtk, and (iii) WxWidget. The problem I ran into then was (a) Qt simply cost too much for the project (due to our budget), and was a security concern - not from the bug aspect but from the aspect that the target market was military and getting Qt certified for the environment would be hard - and a failure there could keep the project from certification as well. WxWidgets and Gtk both has the same security concerns; however, Gtk also had a licensing concern given its LGPL nature and our software was proprietary - Qt provided a great way around that if we could afford it, but we couldn't. So alas I was unable to get into Qt at that time, but as a result I was able to write a good portion of code for doing the same thing - writing my own platform abstraction API.

Now, of the three I loved the ideas and concepts introduced by Qt the best. Gtk, at least at that point, was still very much Message Mapping based from what I could tell. MFC was more than enough of that for me, and was just a pain - everything was determined at compile time and there was little flexibility. One of the great concepts that sold me on Qt was the Signals & Slots system that replaced the message mapping. WxWidgets supported both. Otherwise, all three seemed to be fairly equivalent at that time.

Now, before I go on let me state that I am not trying to convert anyone from Gtk or WxWidgets to Qt with this post. However, if you are using .NET or MFC or anything else (especially on Windows) then you need to start looking elsewhere for numerous reasons which I'll save for another post.

I had written applications in MFC and Win32 for a number of years - both GUI and services. They met the need at the time they were created but are no longer sufficient. .NET, on the other hand, does seem to be vastly updated by comparison but still has quite a few issues - at least patent wise if you want to have portable software.

Now, portable, multi-platform software is going to become ever increasingly important, and unless you are doing certain things that are very tied to a specific environment (e.g. extensions to Windows Explorer or KDE Plasma) then you can reach all your customers on all their platforms with a single code-base using the right tools. WxWidgets, Gtk, and Qt are some of these tools - and probably the best and most portable of all available. They are also Open Source. WxWidgets is completely public domain; while Gtk is solely LGPL. Qt, however, has several licenses - GPL, LGPL, and commercial licenses to choose from, so from a business perspective it makes the best sense - at least, as long as they continue the commercial license program; while from an Open Source perspective all three are really about equal in choice.

All that said, I must certainly say that the creators of Qt have done an excellent job and really gotten the platform right - one that is also continuously improving as well. Perfect just gets better.

So, now why do I say that?

Well, Qt is split into several modules, and they're working on making it more modular yet. Of course, you have to use the core (Qt-core) to use any of it, but the rest is pretty much optional - everything from networking to XML to services (daemons), and more - even in-program scripting. Additionally they also made it very easy to convert from Qt to Standard C++ and back - most all of their classes have functions to convert back and forth where overlapping occurs. The layers make sense and work; consistency abounds throughout the APIs.

So now with a single API you can reach from Linux, to Mac, to UNIX, to Windows; from Desktop to Server to embedded devices (tablets, netbooks, cell phones, specialty devices, etc.). There's not much you'll need a specialized, platform dependent code-base for - which basically comes down to Kernel-land software, and integration environments whose requirements prohibit being able to choose what API set you want to use (e.g. Windows Explorer ala TortoiseSVN). And you get all of it at native performance and looks, with bindings to most languages (e.g. Python, Java, Perl).

Businesses can certainly save themselves a lot of money by using APIs such as Qt, as well as preserve their businesses should anything happen to Microsoft or MS Windows - it's quite a gamble to put all your eggs in one basket, but yet so many software development houses do.