diff options
Diffstat (limited to 'util/fbcompose/plugins/README')
-rw-r--r-- | util/fbcompose/plugins/README | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/util/fbcompose/plugins/README b/util/fbcompose/plugins/README new file mode 100644 index 0000000..6b43356 --- /dev/null +++ b/util/fbcompose/plugins/README | |||
@@ -0,0 +1,204 @@ | |||
1 | FBCOMPOSE PLUGIN DEVELOPMENT GUIDE | ||
2 | |||
3 | Author: Gediminas Liktaras <gliktaras at gmail dot com> | ||
4 | |||
5 | |||
6 | What Is a Plugin | ||
7 | |||
8 | An fbcompose plugin is an .so file, which the compositor loads and uses to | ||
9 | alter the way it renders the desktop. | ||
10 | |||
11 | |||
12 | Getting Started | ||
13 | |||
14 | The easiest way to start is to use one of the existing fbcompose plugins: | ||
15 | 1) Decide which renderer the plugin will be for. | ||
16 | 2) Make a copy of the directory of one of the plugins for that renderer. | ||
17 | 3) Rename .hh and .cc files inside to match your plugin. | ||
18 | 4) Update Makefile.am inside your plugin directory to match your new plugin. | ||
19 | Do not forget to change the name of the shared library (i.e. the *.la | ||
20 | name). | ||
21 | 5) Update SUBDIRS variable in Makefile.am file one directory up so it | ||
22 | includes your plugin directory and add your makefile to configure.in file | ||
23 | the root directory of the repository. | ||
24 | |||
25 | Then when you want to build your plugin, simply build fluxbox as usual. The | ||
26 | .so file will be located in .libs subdirectory. To test it, cd into | ||
27 | util/fbcompose, start the compositor from there and use --plugin flags to | ||
28 | load the plugin as usual. | ||
29 | |||
30 | If you do not want to build fluxbox every time you want compile your plugin, | ||
31 | just change the Makefile.am file to point to wherever fluxbox source code and | ||
32 | libFbTk.a are located. In this case you will have to specify the full path to | ||
33 | the .so file with the --plugin parameter. | ||
34 | |||
35 | The sections below will explain what the compositor expects from the plugin | ||
36 | in detail. | ||
37 | |||
38 | |||
39 | Plugin Shared Object Requirements | ||
40 | |||
41 | All plugins must provide two functions with very specific prototypes, as | ||
42 | detailed below: | ||
43 | |||
44 | * Plugin object creation function. | ||
45 | |||
46 | This function must return an instance of a plugin class, which will perform | ||
47 | all the work of altering the screen's contents. When writing your own | ||
48 | plugin, you should create a class that derives either OpenGLPlugin or | ||
49 | XRenderPlugin (depending on the plugin's type), override its functions as | ||
50 | necessary and finally instantiate and return it in this function. Detailed | ||
51 | information about these two classes can be found below in the "Plugin | ||
52 | Classes" section. | ||
53 | |||
54 | The first parameter is a reference to the screen object that the plugin | ||
55 | object will manipulate and the second parameter is a vector of strings, | ||
56 | which contains the user's plugin configuration. They should be passed to | ||
57 | the plugin object's constructor. | ||
58 | |||
59 | Prototype: | ||
60 | extern "C" FbCompositor::BasePlugin | ||
61 | *createPlugin(const FbCompositor::BaseScreen &screen, | ||
62 | const std::vector<FbTk::FbString> &args); | ||
63 | |||
64 | * Plugin type function. | ||
65 | |||
66 | This function must return one of the values of the PluginType enumeration, | ||
67 | which should match the type of the plugin. This function ensures that the | ||
68 | appropriate plugins are loaded for each renderer. | ||
69 | |||
70 | For an OpenGL plugin it should return Plugin_OpenGL. | ||
71 | |||
72 | For an XRender plugin it should return Plugin_XRender. | ||
73 | |||
74 | Prototype: | ||
75 | extern "C" FbCompositor::PluginType pluginType(); | ||
76 | |||
77 | |||
78 | Plugin Classes | ||
79 | |||
80 | As mentioned above, all plugin objects must inherit some plugin classes. | ||
81 | There are three such classes, whose relationship is the following: | ||
82 | |||
83 | BasePlugin | ||
84 | ^ | ||
85 | +--------+--------+ | ||
86 | | | | ||
87 | OpenGLPlugin XRenderPlugin | ||
88 | |||
89 | BasePlugin | ||
90 | |||
91 | All plugin objects will inherit this class. | ||
92 | |||
93 | This class requires the programmer to define the pluginName function, which | ||
94 | should return the name of the plugin. I highly recommend making sure that | ||
95 | this function returns the name of the plugin's library object. So, if your | ||
96 | plugin will be compiled into foobar.so, pluginName should return "foobar". | ||
97 | |||
98 | All the window* functions are called as soon as the appropriate events are | ||
99 | processed and should be used to keep track of the current window status. | ||
100 | setRoot* functions are called when changes occur to the root window. These | ||
101 | functions should be overriden as necessary. | ||
102 | |||
103 | The screen object and the string vector required by the constructor are | ||
104 | provided with the call to createPlugin function, detailed above. | ||
105 | |||
106 | This class also provides some accessors that may prove useful. | ||
107 | |||
108 | Relevant fbcompose classes: BaseCompWindow, BaseScreen. | ||
109 | |||
110 | OpenGLPlugin | ||
111 | |||
112 | If a plugin wants to work with OpenGL renderer, its objects must come from | ||
113 | a class that inherits OpenGLPlugin. | ||
114 | |||
115 | First, the plugin must return some vertex and fragment shader code. That | ||
116 | code must contain a function, whose name matches the return value of | ||
117 | pluginName function. So, if your plugin is named foobar, the corresponding | ||
118 | vertex shader code that would be | ||
119 | |||
120 | "void foobar() { /* SHADER CODE. */ }" | ||
121 | |||
122 | Even if you do not want to do anything with a particular shader, you must | ||
123 | still declare this shader function. | ||
124 | |||
125 | Attributes, uniforms and samplers can be declared as needed, but it is a | ||
126 | good idea to declare them only as necessary, since it is possible that GPUs | ||
127 | will hit their attribute/uniform/sampler limit with a large number of | ||
128 | plugins loaded. To avoid name clashes, name your | ||
129 | attributes/uniforms/whatever pluginName_VarName (eg. foobar_ShadowTexture, | ||
130 | to continue the previous example). | ||
131 | |||
132 | Rendering action functions fall into four groups: | ||
133 | |||
134 | * Initialization functions that should prepare the plugin shader code | ||
135 | before some part of the screen is rendered. | ||
136 | * Cleanup functions that should do whatever cleanup actions needed after | ||
137 | some part of the screen is rendered. | ||
138 | * Hooks for extra rendering jobs/actions. | ||
139 | * Null rendering job initialization. This function should make sure the | ||
140 | plugin will not interfere with the next rendering job. | ||
141 | |||
142 | The screen is rendered in this order: desktop background, windows, | ||
143 | reconfigure rectangle, extra jobs. The order of the functions within these | ||
144 | groups should be self-evident. | ||
145 | |||
146 | Extra rendering jobs are described with the OpenGLRenderingJob struct, | ||
147 | located in OpenGLPlugin.hh file. All extra jobs are in GL_TRIANGLE mode and | ||
148 | expect to be given four elements, as well as main and shape textures. The | ||
149 | OpenGLScreen object that can be accessed with the appropriate function in | ||
150 | OpenGLPlugin class provides some default buffers and textures, so you don't | ||
151 | have to explicitly create "null" OpenGL objects. | ||
152 | |||
153 | To obtain shader variable locations, extract them from a shader program | ||
154 | wrapper, that is passed to the plugin via initOpenGL function. | ||
155 | |||
156 | Relevant fbcompose classes: OpenGL*. | ||
157 | |||
158 | XRenderPlugin | ||
159 | |||
160 | For a plugin to work with the XRender backend, its objects must inherit the | ||
161 | XRenderPlugin class. | ||
162 | |||
163 | Rendering action functions fall into three groups: | ||
164 | |||
165 | * Plugin damaged area function. | ||
166 | * Initialization functions that can modify the how some particular part of | ||
167 | screen is rendered. | ||
168 | * Hooks for extra rendering jobs/actions. | ||
169 | |||
170 | The screen is rendered in this order: desktop background, windows, | ||
171 | reconfigure rectangle, extra jobs. The order of the functions within these | ||
172 | groups should be self-evident. | ||
173 | |||
174 | Damaged area function should return a vector of all the rectangles that | ||
175 | should be updated in the next frame, since the XRender backend only updates | ||
176 | the damaged areas for performance purposes. It is called before any | ||
177 | rendering is done. | ||
178 | |||
179 | Rendering jobs are described with the XRenderRenderingJob struct, located | ||
180 | in XRenderPlugin.hh file. It essentially contains all the parameters of the | ||
181 | XRenderComposite function. If operation equals PictOpClear, the rendering | ||
182 | job is ignored. | ||
183 | |||
184 | |||
185 | Plugin Distribution | ||
186 | |||
187 | In addition to sharing the source code of a plugin, you could also distribute | ||
188 | precompiled .so files, which the users simply have to place into an | ||
189 | appropriate directory to use them. | ||
190 | |||
191 | If you choose this option, do pay attention to your machine architecture. If | ||
192 | you can, try to provide both 32 bit and 64 bit binaries. If you are on a 64 | ||
193 | bit machine, you can create a 32 bit binary with -m32 g++ flag, for example. | ||
194 | |||
195 | |||
196 | Miscellaneous Notes | ||
197 | |||
198 | * Make sure your plugin names begin with a letter and consist only of | ||
199 | alphanumeric characters and underscores. Also make sure that this name does | ||
200 | not match any of the keywords in GLSL and matches both the name of the .so | ||
201 | file and the string returned by the BaseScreen::pluginName function. | ||
202 | |||
203 | * It is not necessary to keep plugin rendering action function stateless, as | ||
204 | long as you keep in mind when and in what order the functions are called. | ||