/lcdhost

Automatically exported from code.google.com/p/lcdhost

Primary LanguageC

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 *un*versioned 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
*********************************************************************

  * This section is a work in progress. *

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\"?>"
  "<lcdhostplugin>"
    "<id>MyLCDHostPlugin</id>"
    "<rev>" STRINGIZE(REVISION) "</rev>"
    "<api>" STRINGIZE(LH_API_MAJOR) "." STRINGIZE(LH_API_MINOR) "</api>"
    "<ver>" "r" STRINGIZE(REVISION) "</ver>"
    "<versionurl></versionurl>"
    "<author>My Name</author>"
    "<homepageurl>http://my.home.page</homepageurl>"
    "<logourl></logourl>"
    "<shortdesc>"
    "What my plugin does"
    "</shortdesc>"
    "<longdesc>"
    "Detailed instructions and help"
    "</longdesc>"
  "</lcdhostplugin>";

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.