Mercurial > pidgin
annotate doc/C-HOWTO.dox @ 15564:45d3dd67fa13
With the refactoring I did, it's now possible to reach timestamp_cb_common
with conv == NULL. It happens with system logs. I've reworked the code
accordingly to avoid an assertion failure.
| author | Richard Laager <rlaager@wiktel.com> |
|---|---|
| date | Mon, 05 Feb 2007 05:28:54 +0000 |
| parents | 09900227d1b9 |
| children | 874d55d836bc |
| rev | line source |
|---|---|
| 10468 | 1 /** @page c-howto C Plugin HOWTO |
| 2 | |
| 3 @section Introduction | |
| 4 C plugins are native plugins. They have complete access to all of the api, | |
| 5 and can do basically whatever they want. All of the protocol plugins, as | |
| 6 well as the perl and tcl loader plugins are written in C. | |
| 7 | |
| 8 @section getting_started Getting Started | |
| 10469 | 9 To develop a plugin you need to have the Gaim source code. It is generally a |
| 10 good idea to compile against the same version of Gaim that you are running. | |
| 14502 | 11 You may also want to develop against SVN. While we do NOT recomend this for |
| 12 normal users, it makes sense for plugin developers to use SVN to ensure their | |
| 10469 | 13 plugins works with the most recent changes in Gaim. A lot tends to |
| 10468 | 14 change between versions and it's much easier to fix your plugin as things |
| 14502 | 15 change rather than waiting until the release. But please do not abuse SVN. |
| 16 Gaim puts a lot of strain on SourceForge's servers, and we do not need to | |
| 10468 | 17 add anymore to it. |
| 18 | |
| 10469 | 19 If you choose not to head my warnings and develop against a version of Gaim |
| 20 that is different from what you're running, then your Gaim source must at | |
| 10468 | 21 the very least be configured. Note that just running configure will |
| 22 generally set the prefix to /usr/local. This shouldn't be a problem, except | |
| 10469 | 23 that most packages compile and install Gaim with /usr as the prefix. |
| 10468 | 24 |
| 25 All plugins must have @c GAIM_PLUGINS defined. You can choose to include | |
| 26 @c internal.h to do this, but if you choose to do it this way it must be | |
| 10469 | 27 included before any other Gaim files. Likewise, if you choose to manually |
| 28 define @c GAIM_PLUGINS, the definition must be before including any Gaim | |
| 10468 | 29 files. Failure to do so will produce the 'plugin foo could not be loaded for |
| 30 an unknown reason'. This is one of the hardest unknown reasons to track | |
| 31 down, so let's try to avoid it at all costs ;) | |
| 32 | |
| 33 @section hello_world Hello World! | |
| 10469 | 34 I know every tutorial has a hello world, so why should Gaim be any different? |
| 10468 | 35 |
| 36 @code | |
| 37 #define GAIM_PLUGINS | |
| 38 | |
| 39 #include <glib.h> | |
| 40 | |
| 41 #include "notify.h" | |
| 42 #include "plugin.h" | |
| 43 #include "version.h" | |
| 44 | |
| 45 static gboolean | |
| 46 plugin_load(GaimPlugin *plugin) { | |
| 47 gaim_notify_message(plugin, GAIM_NOTIFY_MSG_INFO, "Hello World!", | |
| 48 "This is the Hello World! plugin :)", NULL, NULL, NULL); | |
| 49 | |
| 50 return TRUE; | |
| 51 } | |
| 52 | |
| 53 static GaimPluginInfo info = { | |
| 54 GAIM_PLUGIN_MAGIC, | |
| 55 GAIM_MAJOR_VERSION, | |
| 56 GAIM_MINOR_VERSION, | |
| 57 GAIM_PLUGIN_STANDARD, | |
| 58 NULL, | |
| 59 0, | |
| 60 NULL, | |
| 61 GAIM_PRIORITY_DEFAULT, | |
| 62 | |
| 63 "core-hello_world", | |
| 64 "Hello World!", | |
| 65 VERSION, | |
| 66 | |
| 67 "Hello World Plugin", | |
| 68 "Hello World Plugin", | |
| 69 NULL, | |
|
13895
8f910263b4bb
[gaim-migrate @ 16380]
Richard Laager <rlaager@wiktel.com>
parents:
10469
diff
changeset
|
70 "http://www.helloworld.tld", |
| 10468 | 71 |
| 72 plugin_load, | |
| 73 NULL, | |
| 74 NULL, | |
| 75 | |
| 76 NULL, | |
| 77 NULL, | |
| 78 NULL, | |
| 79 NULL | |
| 80 }; | |
| 81 | |
| 82 static void | |
| 83 init_plugin(GaimPlugin *plugin) { | |
| 84 } | |
| 85 | |
| 86 GAIM_INIT_PLUGIN(hello_world, init_plugin, info); | |
| 87 | |
| 88 @endcode | |
| 89 | |
| 90 Okay, so what does all this mean? We start off by defining @c GAIM_PLUGINS | |
| 91 like described before. Next we include glib.h, mainly for gboolean and the | |
| 92 glib wrappers of the standard c types. We could just use stdio and use | |
| 10469 | 93 an int for the gboolean but since Gaim uses glib internally, we might as |
| 10468 | 94 well do the same. |
| 95 | |
| 96 Next, we include plugin.h which has all the plugin specific stuff that we | |
| 97 need. For example @c GaimPlugin, @c GaimPluginInfo, @c GAIM_PLUGIN_MAGIC, | |
| 98 and @c GAIM_INIT_PLUGIN(). | |
| 99 | |
| 100 Our last include is version.h which defines @c GAIM_MAJOR_VERSION, and | |
| 10469 | 101 @c GAIM_MINOR_VERSION. There is not much you need to know about these, |
| 102 except that they are required and will stop your plugin from crashing Gaim | |
| 103 when something has changed that you plugin does not know about yet. | |
| 10468 | 104 |
| 10469 | 105 plugin_load is not required. It is called when the plugin is loaded so that |
| 106 you can initialize any variables and so on. But in this plugin we'll just | |
| 107 use it to display a message. | |
| 10468 | 108 |
| 109 Next we have the @c GaimPluginInfo structure. Every plugin MUST have one of | |
| 110 these. Below is a code snipet of the same struct used in @c hello_world with | |
| 111 comments describing what each is. | |
| 112 | |
| 113 @code | |
| 114 static GaimPluginInfo info = { | |
| 115 GAIM_PLUGIN_MAGIC, /* Plugin magic, this should always be | |
| 116 GAIM_PLUGIN_MAGIC. This value gets | |
| 10469 | 117 incremented inside of Gaim so that plugins |
| 118 that haven't been updated yet will fail to | |
| 10468 | 119 load and avoid potential crashes while |
| 120 loading old plugins. | |
| 121 */ | |
| 10469 | 122 GAIM_MAJOR_VERSION, /* This is also defined in Gaim. It helps |
| 123 Gaim's plugin system determine what version | |
| 124 of Gaim this plugin was compiled for, and | |
| 125 whether loading it will cause problems. | |
| 10468 | 126 */ |
| 127 GAIM_MINOR_VERSION, /* See previous */ | |
| 128 GAIM_PLUGIN_STANDARD, /* GaimPluginType, there are 4 different values | |
| 129 for this field. The first is | |
| 130 GAIM_PLUGIN_UNKNOWN, which should not be | |
| 131 used. The second is GAIM_PLUGIN_STANDARD, | |
| 132 this is the value most plugins will use. | |
| 133 Next we have GAIM_PLUGIN_LOADER, this is | |
| 10469 | 134 the type you want to load if your plugin |
| 135 is going to make it possible to load non- | |
| 10468 | 136 native plugins. For example, perl and tcl. |
| 137 Last, we have GAIM_PLUGIN_PROTOCOL. If | |
| 138 your plugin is going to allow the user to | |
| 139 connect to another network, this is the | |
| 140 type you'd want to use. | |
| 141 */ | |
| 142 NULL, /* This field is the ui requirement. This | |
| 143 value should be a string. If you're | |
| 144 writing a core plugin, this should be NULL | |
| 145 and the plugin should not contain any ui | |
| 146 specific code. If you're writing a gtk | |
| 147 plugin, you can use the | |
| 148 GAIM_GTK_PLUGIN_TYPE macro. All other ui | |
| 149 plugins are dependent on their ui | |
| 150 implementation, and is outside the scope of | |
| 151 this howto. | |
| 152 */ | |
| 153 0, /* This field is for plugin flags. Currently, | |
| 154 the only flag available to plugins is | |
| 155 invisible (GAIM_PLUGIN_FLAG_INVISIBLE). | |
| 10469 | 156 This plugin is currently used by the ssl |
| 157 plugin, the tcl loader, and the perl | |
| 158 loaded. It causes the plugin to NOT | |
| 159 appear in the list of plugins in Gaim's | |
| 160 preferences window. | |
| 10468 | 161 */ |
| 10469 | 162 NULL, /* This is a GList of plugin dependencies. In |
| 163 other words, a GList of plugin id's that | |
| 10468 | 164 your plugin depends on. If your plugin |
| 165 does not have any dependencies, set this | |
| 10469 | 166 value to NULL. |
| 10468 | 167 */ |
| 10469 | 168 GAIM_PRIORITY_DEFAULT, /* This is the priority Gaim with give your |
| 10468 | 169 plugin. There are three possible values |
| 170 for this field, GAIM_PRIORITY_DEFAULT, | |
| 171 GAIM_PRIORITY_HIGHEST, and | |
| 172 GAIM_PRIORITY_LOWEST | |
| 173 */ | |
| 174 | |
| 175 "core-hello_world", /* This is your plugin's id. There is a whole | |
| 176 page dedicated to this in the | |
| 10469 | 177 'related-pages' section of Gaim's API docs. |
| 10468 | 178 */ |
| 179 "Hello World!", /* This is your plugin name. This is what | |
| 180 will be displayed for your plugin in the ui. | |
| 181 */ | |
| 10469 | 182 1.1, /* This is the version of your plugin. For |
| 183 the sake of simplicity, I'm using the Gaim | |
| 10468 | 184 version. |
| 185 */ | |
| 186 | |
| 187 "Hello World Plugin", /* This is the summary of your plugin. It | |
| 188 should be a short little blurb. The ui | |
| 189 determines where, if at all, to display | |
| 190 this. | |
| 191 */ | |
| 192 "Hello World Plugin", /* This is the description of your plugin. It | |
| 193 can be as long and as descriptive as you | |
| 194 like. And like the summary, it's up to the | |
| 195 ui where, if at all, to display this. | |
| 196 */ | |
| 197 NULL, /* This is where you can put your name and | |
| 198 email address. (You are the author right?) | |
| 199 */ | |
|
13895
8f910263b4bb
[gaim-migrate @ 16380]
Richard Laager <rlaager@wiktel.com>
parents:
10469
diff
changeset
|
200 "http://www.helloworld.tld", /* This is the website for the plugin. This |
| 10468 | 201 is helpful if users find bugs in your |
| 202 plugin so they can help to bring them to | |
| 10469 | 203 your attention. |
| 10468 | 204 */ |
| 205 | |
| 10469 | 206 plugin_load, /* This is a pointer to a function for Gaim to |
| 10468 | 207 call when it is loading your plugin. It |
| 208 should be in the form of: | |
| 209 | |
| 210 gboolean function_name(GaimPlugin *plugin) | |
| 211 | |
| 10469 | 212 Returning TRUE will tell Gaim to continue |
| 10468 | 213 loading your plugin, while FALSE will tell |
| 10469 | 214 Gaim to stop trying to load it. |
| 10468 | 215 */ |
| 216 NULL, /* Same as above except it is called when | |
| 10469 | 217 Gaim tries to unload your plugin. It |
| 10468 | 218 should be in the form of: |
| 219 | |
| 220 gboolean function_name(GaimPlugin *plugin) | |
| 221 | |
| 10469 | 222 Where returning TRUE will tell Gaim to |
| 10468 | 223 continue unloading and false to not continue |
| 224 unloading your plugin. | |
| 225 */ | |
| 226 NULL, /* Similar to the two above members, except | |
| 10469 | 227 this is called when Gaim tries to destory |
| 10468 | 228 the plugin. This is generally only called |
| 229 when for some reason or another the plugin | |
| 230 fails to probe correctly. It should be in | |
| 231 the form of: | |
| 232 | |
| 233 void function_name(GaimPlugin *plugin) | |
| 234 */ | |
| 235 | |
| 236 NULL, /* This is a pointer to a ui specific struct. | |
| 237 For a gtk plugin it will be a pointer to a | |
| 238 GaimGtkPluginUiInfo struct. | |
| 239 */ | |
| 240 NULL, /* This is a pointer to either a | |
| 241 GaimPluginLoaderInfo struct or a | |
| 242 GaimPluginProtocolInfo struct, and is | |
| 243 beyond the scope of this document. | |
| 244 */ | |
| 245 NULL, /* This is a pointer to a GaimPluginUiInfo | |
| 246 struct. It is a core/ui split way for | |
| 247 core plugins to have a ui configuration | |
| 248 frame. You can find an example of this | |
| 249 code in plugins/pluginpref_example.c | |
| 250 */ | |
| 251 NULL /* Finally the last member of the structure, | |
| 252 is a function pointer where you can define | |
| 253 menu entries for 'Tools->Plugin Actions'. | |
| 254 It should be in the form of: | |
| 255 | |
| 256 GList *function_name(GaimPlugin *plugin, | |
| 257 gpointer context) | |
| 258 | |
| 259 It should return a GList of | |
| 260 GaimPluginActions. | |
| 261 */ | |
| 262 }; | |
| 263 @endcode | |
| 264 | |
| 265 Finally we have @c init_plugin and @c GAIM_INIT_PLUGIN. @c init_plugin is a | |
| 266 function that gets called when Gaim probes the plugin. Most plugins will | |
| 267 add their preferences to the pref tree here, more about that later. | |
| 10469 | 268 @c GAIM_INIT_PLUGIN is a macro that EVERY plugin MUST have. @c GAIM_INIT_PLUGIN |
| 269 tells Gaim some very basic things about your plugin, like what name to use | |
| 10468 | 270 if the plugin is compiled staticly, the @c init_plugin function, and |
| 271 the name of the @c GaimPluginInfo structure. As you may have guess this | |
| 272 also gets read when Gaim is probing your plugin. If this is missing you | |
| 273 will get the infamous "plugin unloadable for unknown reasons", so do not | |
| 274 forget it. | |
| 275 */ |
