This is the top level directory for the open source parts of LCDHost.
It contains everything needed to build LCDHost plugins, with some extra attention to doing it using Qt. By default, simply opening the lcdhost.pro file in Qt Creator should let you build unsigned versions all of the plugins.
Some plugins may not build on all platforms, or build but provide only limited features.
*** Do I really need all this stuff?
The reasonable minimum to get if you use the Qt SDK is the "lcdhost.pro" file and the "linkdata" subdirectory.
The Qt SDK may be found at http://qt.nokia.com/products/qt-sdk
*** What NOT to change
Do NOT commit files at the top level, such as altering or removing existing files or adding new ones. The top level directory should only contain this "README", "lcdhost.pro" and ".hgignore".
You may of course add any unversioned files anywhere. Just be very careful not to add them to the repository by mistake.
If you want to add your own plugin subdirectory to the repository, that's fine as long as it compiles cleanly on both OS/X and Windows. If you can't test on either of those, see LH_LCoreReboot.pro for an example on how to limit a plugin to a single architecture.
Do NOT commit to the project members private directories. Create a issue on the issue tracker about any bugs or problems that they need to adress, and label the issue appropriately.
http://code.google.com/p/lcdhost/issues/list
The private directories and their maintainers are: linkdata/ - maintained by Johan Lindh johan@linkdata.se codeleap/ - maintained by Andy Bridges andy@bridgesuk.com
*** Keeping your code inside the repository
It's fine to keep your code in a subdirectory of the repository root. In fact, it simplifies things a lot. Just read the "What NOT to change" bit above again.
If you prefer to keep your source code closed, you can do that too while still keeping it inside the repository root. Just don't add it to the LCDHost repository.
*** Configuring your build preferences
You should create a file named "lcdhost.prf" in the top level repository directory. This is fine as it's both in ".hgignore" and you're not going to add it to the repository.
This file will be included by "lcdhost.pro" to set the LH_PLUGINS_LIST variable that decides which plugins to build. It will also be included by the plugin project files, so you should configure any extra build steps there as well.
If lcdhost.prf does not exist, lcdhost.pro will create a default one for you.
Sample contents to build and sign a single plugin on Windows, assuming that the private key file is at c:/Users/UserName/private.pem and the public key can be downloaded from http://my.website/public.pem:
LH_PLUGINS_LIST = MyPlugin
CONFIG(debug): LH_DESTDIR=$$PWD/debug
else: LH_DESTDIR=$$PWD/release
SIGNATURE_PRIVATE_FILE = c:/Users/UserName/private.pem
SIGNATURE_PUBLIC_URL = http://my.website/public.pem
load($$PWD/linkdata/linkdata.prf)
include($$PWD/linkdata/SignPlugin.pri)
*** Building inside the repository
While possible, it tends to clutter up the filesystem and the output of "hg status". The former is traditionally handled using build targets named "clean", "mrproper" and other silly things. The latter is usually handled by putting more and more glob's into ".hgignore".
Personally, I prefer to use Qt Creator's "Shadow Build" option, which leaves the repository alone while building.
*** How to build a LCDHost plugin with Qt Creator
You should already have cloned the repository so you can work on it. See http://code.google.com/p/lcdhost/source/checkout if you need help.
By custom, and to trivially identify them as probable LCDHost plugins, we start all plugin projects with 'LH_'. So, assuming you want to call your plugin 'MyLCDHostPlugin', we'll call the project LH_MyLCDHostPlugin.
*** Creating a skeleton C++ shared library with Qt Creator
We'll create a skeleton C++ shared library project with our chosen project name. We'll assume that is "LH_MyLCDHostPlugin" here. In Qt Creator, select the menu item File -> New file or Project.
In the "New" dialog, choose the Project template "Other Project" from the upper left list. Then select "C++ Library" from the right hand list. Click "Choose".
The "C++ Library" dialog prompts for the type of library, it's name and it's location. Select "Shared Library", enter "LH_MyLCDHostPlugin" for the name.
For "Create in", select the directory where this file and the lcdhost.pro file is. Don't worry, this is under source control, so even if you mess up you can clean up afterwards. Click "Next".
You now get a "Target setup" dialog. Not much to do here. You may want to have "Use Shadow Building" checked, or Qt will clutter up the repository filesystem with it's generated Makefiles and other intermediate files. Make sure "Desktop" is checked. Let it create build configurations as it's suggesting. Click "Next".
You now get to "Select Required Modules". For all LCDHost plugins written with Qt, you'll need QtCore and QtGui. QtCore is already checked for you. Check QtGui. Anything else requires you to know what the respective Qt modules do, so leave them unchecked unless you're a Qt professional. WARNING: Do NOT include QtWebKit. It's not suitable for use in a threaded environment. If you need render webpages, you should be using LH_WebKit. When done, click "Next".
The new dialog allows you to confirm and make last adjustments to class and file names. Click "Next".
The "Project Management" dialog may be your first indication that you're working within a mercurial repository. Here, you'll need to change the "Add to project" box so it reads "None". (Unless you're a committer on the project, but then, why are you reading this?). Then click "Finish".
You now have a skeleton project capable of building a multiplatform generic shared library. It doesn't do anything, and isn't recognized by LCDHost as a possible plugin, but it's a start, and all you've had to do is click some buttons!
*** Configuring your build
This step is optional, but you might as well read it, or you'll get confused if you accidentally build using lcdhost.pro.
Usually, you don't want to build all the plugins. It takes a long time, and you very likely already have them. Therefore lcdhost.pro looks for a file called "lcdhost.prf". It expects it to define a variable called "LH_PLUGINS_LIST", which is a list of the plugins that should be built, in order.
In the directory with lcdhost.pro, create a text file named "lcdhost.prf" containing the text
LH_PLUGINS_LIST = LH_MyLCDHostPlugin
load($$PWD/linkdata/PluginsBase.prf)
*** Creating a LH_QtPlugin descendant with Qt Creator
Now you need to add in the LCDHost bits. First, add this line to your LH_MyLCDHostPlugin.pro file, after the "DEFINES += LH_MYLCDHOSTPLUGIN_LIBRARY" line but before "SOURCES += LH_MyLCDHostPlugin.cpp"
load(../../lcdhost.prf)
This tells qmake to first try including the lcdhost.prf file we just made.
This should pull in the basic header files, include paths, sources and libraries needed to build a LCDHost plugin. Next you need to create a C++ class that inherits from LH_QtPlugin. So let's do that.
In Qt Creator, select the menu item File -> New file or Project. From the lower left list "Files and Classes", select "C++". In the right hand list, select "C++ Class". Click "Choose...".
For the class name, you can pick anything you like, but other plugins usually follow the convention "LH_QtPlugin_MyLCDHostPlugin". For "Base class", enter LH_QtPlugin. For "Type information", select "Inherits QObject".
Examine the generated values for "Header file", "Source file". Change them if you prefer a different naming scheme (upper/lowercase etc). Closely examine the value for "Path". Qt Creator sometimes get confused about where to put things, but it should point to the newly created "LH_MyLCDHostPlugin" subdirectory under the checked out repository root. Click "Next".
The "Project Management" dialog is here again! This time though, it should be spot on. We want "Add to project" to read "LH_MyLCDHostPlugin.pro" and "Add to version control" to be whichever VCS you're using, probably "Mercurial" if you checked out with hg. Make a final check on the file names and where they're going to be created, and then click "Finish".
Next, we need to modify the newly created header so it includes the base class. Add the line
#include "LH_QtPlugin.h"
before the line
class LH_QtPlugin_MyLCDHostPlugin : public LH_QtPlugin
At this point the code should compile. It won't be recognized by LCDHost as a valid plugin yet - there's a bit more to that.
*** Adding the LCDHost plugin specific bits
Next we need to add the embedded XML document that identifies this as a LCDHost plugin, and create the required shared library exports so that LCDHost will be able to to load it as a plugin. There's a simple macro for all this. The macro goes into the implementation file, NOT the header file. So add this text to the end of LH_QtPlugin_MyLCDHostPlugin.cpp:
LH_PLUGIN(LH_QtPlugin_MyLCDHostPlugin) =
"<?xml version=\"1.0\"?>"
"
This has three effects. First, it creates an blank signature area that you can later fill in with SignPlugin if you choose. (You can automate this procedure, see linkdata/SignPlugin.pri). While a plugin is valid without having a signature area, it is strongly recommended to have one.
The second thing it does is define and export the plugin class so Qt can load it.
Third, it embeds the required XML document into the plugin. Without that, LCDHost won't recognize it as a valid plugin.
That's it. You now have a bare bones LCDHost plugin. LCDHost will recognize it and load/unload it. It doesn't actually provide any features, but that's for another README.
*** Further reading
For Qt C++ plugins, examine LH_Text. For pure C plugins, examine LH_Image.