808fd580aa3fcfe5b080e9de844ff1a1f3666b2c
[openblackhole/openblackhole-enigma2.git] / doc / PLUGINS
1 enigma2 plugins
2 ===============
3
4 Enigma2 plugins are always written in python. If you really have to call
5 C/C++ functions from your code, you can supply a python module with it,
6 implementing your functions.
7
8 Let's write a plugin. We call it "OurSmallTest", and it should be a test
9 plugin. Thus we choose "DemoPlugins" as a category. The category is just to
10 organize plugins in the filesystem.
11
12 The simplest plugin looks like the following:
13
14 Plugins/DemoPlugins/OurSmallTest/plugin.py:
15
16 "from Plugins.Plugin import PluginDescriptor
17
18 def main(session, **kwargs):
19         print "Hello world!"
20
21 def Plugins(**kwargs):
22         return PluginDescriptor(
23                 name="Our Small Test", 
24                 description="plugin to test some capabilities", 
25                 where = PluginDescriptor.WHERE_PLUGINMENU,
26                 fnc=main)"
27
28 Basically, you're writing a "python module", which is called
29 Plugins.DemoPlugins.OurSmallTest.plugin. This corresponds to the
30 Plugins/DemoPlugins/OurSmallTest/plugin.py file.
31
32 This module must define a single function called "Plugins". The functions is
33 called for every Plugin, and should return (a list of)
34 PluginDescriptor-Objects. A PluginDescriptor is a simple object, holding the
35 Plugin's name, description, picture etc., and an entry point.
36
37 In the first line, we import that class. It's contained in a module called
38 Plugins.Plugin.
39
40 At the end, we define the "Plugins"-Functions. As said, it returns a
41 constructed PluginDescriptor-object (in fact it can return either one or a
42 list of descriptors, here it returns exactly one). We use keyword arguments
43 to supply the Plugin's information, like the name, the descripttion etc.
44
45 We also supply an entry point, called "fnc". It's set to the "main"
46 function, which is defined before. Our entry point is called with a number
47 of arguments, depending on where the plugin was launched from. In this case,
48 it's a "session" argument. You need the session argument if you want to do
49 graphical output. A session basically connects to "user". There is always
50 one sessions which corresponds to the main screen output, but there can also
51 be other sessions, which yet have to be implemented. (A possible example is a
52 networked remote session.) If you don't need that argument, just ignore it.
53
54 A plugin can decide where it wants to be displayed. A possible example is
55 the plugin menu out of the main menu. In the "where" argument to the
56 descriptor, you can supply one (or a list of) "WHERE_"-identifiers. We use
57 WHERE_PLUGINMENU. There will be other ones, for example for the blue button,
58 or specific other menus.
59
60 Now, if you copy this plugin in-place, it should be listed in the plugin
61 browser in the main menu. You can press "ok" on the plugin, and the "main"
62 function, which was specified as the plugin's entry point, is executed.
63
64 If you want to open a graphical screen, you might want the entry point to
65 look like:
66
67 def main(session):
68         session.open(MyScreen)
69
70 with MyScreen being a GUI screen.
71
72 About the **kwargs:
73 This somewhat special syntax (in fact the name 'kwargs' is arbitrary, but
74 stands for "keyword arguments") collects all addition keyword arguments
75 (i.e. named parameters). For example. the Plugins()-call gets a "path"
76 parameter, and probably more in the future. You must ignore all additional
77 keywords which you don't need!
78
79 skins
80 =====
81
82 Generally, you can include the skin in your Screens by having a static (or
83 non-static, if you really want) variable "skin", for example:
84
85 class OurSmallTestScreen(Screen):
86         skin = "<skin>...</skin>"
87         def __init__(self, session):
88                 Screen.__init__(self, session)
89                 ...
90
91 However, users can override the skin from their skin.xml. Note that the
92 Screen's name (unless you override this, which is possible) is used for
93 determining which skin is used. Thus, if you're choosing generic skin names
94 like "TheScreen", it's likely to cause namespace clashes.
95
96 Thus, please use skin names (i.e. Screen-names, unless you're overriding the
97 skin name) which are unique enough to not clash. In doubt, prepend the
98 pluginname like in our example.
99
100 autostarting plugins
101 ====================
102
103 you can configure your plugin to automatically start on enigma startup, and
104 end on shutdown.
105
106 you just have to use "WHERE_AUTOSTART". your entry point must (fnc) look 
107 like:
108
109 def autostartEntry(raeson, **kwargs):
110         if reason == 0: # startup
111                 print "startup"
112         elif reason == 1:
113                 print "shutdown"
114
115 autostart plugins should always be configurable, and should default to an
116 OFF state!
117
118 Configuration
119 =============
120
121 Speaking about configuration, plugins must live in 
122
123 config.plugins.<Category>.<PluginName>
124
125 and nowhere else!
126
127 You are, however, free to change settings which are already existing. If you
128
129 Dependencies
130 ============
131
132 Plugin dependencies (one plugin requires another plugin) should generally be
133 avoided, but are possible. If there are dependencies, the .ipk file must
134 list them.
135
136 If possible, make them optional. If your plugin doesn't support one feature
137 because another plugin isn't installed, that's fine (but should be noted in
138 the docs).
139
140 Categories
141 ==========
142
143 Currently defined categories are:
144
145 * DemoPlugins: Plugins fore pure demonstration purposes
146 * Extensions: User interface extensions
147 * SystemPlugins: Hardware specific plugins
148
149 Plugin Names
150 ============
151
152 A plugin name:
153  - should always start with a Uppercase letter,
154  - must not start with the word "Dream",
155  - nor end with "Plugin",
156  - should be unique even across Categories,
157  - must be understandable by english speaking people,
158    (unless it's a geographically restricted plugin)
159  - is not user changeable (that is, the user is not allowed to rename the
160    plugin directory)
161  - shouldn't be a generic word