Sat, 26 Aug 2006 06:25:49 +0000
[gaim-migrate @ 17035]
Fixes SF Bug # 1373116 (and related Debian Bug #341607)
Fix the Find functionality in the log viewer. It now properly scrolls to the first occurrence of the search term. Also, clicking the Find button will now jump to the next occurrence of the search term, including wrapping around to the top.
Possible Badness:
This changes the behavior of all IMHTML searches. Previously, if you kept calling gtk_imhtml_search_find(), it'd clear the highlighting when you went past the last occurrence of the search term. This seems wrong. I believe it should either stop or wrap around to the top. Wrapping around seemed most useful to me, so that's what I implemented.
This was inspired by SF Patch #1545488 by Mark Schneider
| 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
3edb0348ba88
[gaim-migrate @ 11751]
Mark Doliner <markdoliner@pidgin.im>
parents:
10468
diff
changeset
|
9 | To develop a plugin you need to have the Gaim source code. It is generally a |
|
3edb0348ba88
[gaim-migrate @ 11751]
Mark Doliner <markdoliner@pidgin.im>
parents:
10468
diff
changeset
|
10 | good idea to compile against the same version of Gaim that you are running. |
| 10468 | 11 | You may also want to develop against CVS. While we do NOT recomend this for |
|
10469
3edb0348ba88
[gaim-migrate @ 11751]
Mark Doliner <markdoliner@pidgin.im>
parents:
10468
diff
changeset
|
12 | normal users, it makes sense for plugin developers to use CVS to ensure their |
|
3edb0348ba88
[gaim-migrate @ 11751]
Mark Doliner <markdoliner@pidgin.im>
parents:
10468
diff
changeset
|
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 |
| 15 | change rather than waiting until the release. But please do not abuse CVS. | |
| 16 | Gaim puts a lot of strain on Source Forge's servers, and we do not need to | |
| 17 | add anymore to it. | |
| 18 | ||
|
10469
3edb0348ba88
[gaim-migrate @ 11751]
Mark Doliner <markdoliner@pidgin.im>
parents:
10468
diff
changeset
|
19 | If you choose not to head my warnings and develop against a version of Gaim |
|
3edb0348ba88
[gaim-migrate @ 11751]
Mark Doliner <markdoliner@pidgin.im>
parents:
10468
diff
changeset
|
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
3edb0348ba88
[gaim-migrate @ 11751]
Mark Doliner <markdoliner@pidgin.im>
parents:
10468
diff
changeset
|
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
3edb0348ba88
[gaim-migrate @ 11751]
Mark Doliner <markdoliner@pidgin.im>
parents:
10468
diff
changeset
|
27 | included before any other Gaim files. Likewise, if you choose to manually |
|
3edb0348ba88
[gaim-migrate @ 11751]
Mark Doliner <markdoliner@pidgin.im>
parents:
10468
diff
changeset
|
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
3edb0348ba88
[gaim-migrate @ 11751]
Mark Doliner <markdoliner@pidgin.im>
parents:
10468
diff
changeset
|
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, | |
|
13957
c6ca17e312aa
[gaim-migrate @ 16380]
Richard Laager <rlaager@pidgin.im>
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
3edb0348ba88
[gaim-migrate @ 11751]
Mark Doliner <markdoliner@pidgin.im>
parents:
10468
diff
changeset
|
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
3edb0348ba88
[gaim-migrate @ 11751]
Mark Doliner <markdoliner@pidgin.im>
parents:
10468
diff
changeset
|
101 | @c GAIM_MINOR_VERSION. There is not much you need to know about these, |
|
3edb0348ba88
[gaim-migrate @ 11751]
Mark Doliner <markdoliner@pidgin.im>
parents:
10468
diff
changeset
|
102 | except that they are required and will stop your plugin from crashing Gaim |
|
3edb0348ba88
[gaim-migrate @ 11751]
Mark Doliner <markdoliner@pidgin.im>
parents:
10468
diff
changeset
|
103 | when something has changed that you plugin does not know about yet. |
| 10468 | 104 | |
|
10469
3edb0348ba88
[gaim-migrate @ 11751]
Mark Doliner <markdoliner@pidgin.im>
parents:
10468
diff
changeset
|
105 | plugin_load is not required. It is called when the plugin is loaded so that |
|
3edb0348ba88
[gaim-migrate @ 11751]
Mark Doliner <markdoliner@pidgin.im>
parents:
10468
diff
changeset
|
106 | you can initialize any variables and so on. But in this plugin we'll just |
|
3edb0348ba88
[gaim-migrate @ 11751]
Mark Doliner <markdoliner@pidgin.im>
parents:
10468
diff
changeset
|
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
3edb0348ba88
[gaim-migrate @ 11751]
Mark Doliner <markdoliner@pidgin.im>
parents:
10468
diff
changeset
|
117 | incremented inside of Gaim so that plugins |
|
3edb0348ba88
[gaim-migrate @ 11751]
Mark Doliner <markdoliner@pidgin.im>
parents:
10468
diff
changeset
|
118 | that haven't been updated yet will fail to |
| 10468 | 119 | load and avoid potential crashes while |
| 120 | loading old plugins. | |
| 121 | */ | |
|
10469
3edb0348ba88
[gaim-migrate @ 11751]
Mark Doliner <markdoliner@pidgin.im>
parents:
10468
diff
changeset
|
122 | GAIM_MAJOR_VERSION, /* This is also defined in Gaim. It helps |
|
3edb0348ba88
[gaim-migrate @ 11751]
Mark Doliner <markdoliner@pidgin.im>
parents:
10468
diff
changeset
|
123 | Gaim's plugin system determine what version |
|
3edb0348ba88
[gaim-migrate @ 11751]
Mark Doliner <markdoliner@pidgin.im>
parents:
10468
diff
changeset
|
124 | of Gaim this plugin was compiled for, and |
|
3edb0348ba88
[gaim-migrate @ 11751]
Mark Doliner <markdoliner@pidgin.im>
parents:
10468
diff
changeset
|
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
3edb0348ba88
[gaim-migrate @ 11751]
Mark Doliner <markdoliner@pidgin.im>
parents:
10468
diff
changeset
|
134 | the type you want to load if your plugin |
|
3edb0348ba88
[gaim-migrate @ 11751]
Mark Doliner <markdoliner@pidgin.im>
parents:
10468
diff
changeset
|
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
3edb0348ba88
[gaim-migrate @ 11751]
Mark Doliner <markdoliner@pidgin.im>
parents:
10468
diff
changeset
|
156 | This plugin is currently used by the ssl |
|
3edb0348ba88
[gaim-migrate @ 11751]
Mark Doliner <markdoliner@pidgin.im>
parents:
10468
diff
changeset
|
157 | plugin, the tcl loader, and the perl |
|
3edb0348ba88
[gaim-migrate @ 11751]
Mark Doliner <markdoliner@pidgin.im>
parents:
10468
diff
changeset
|
158 | loaded. It causes the plugin to NOT |
|
3edb0348ba88
[gaim-migrate @ 11751]
Mark Doliner <markdoliner@pidgin.im>
parents:
10468
diff
changeset
|
159 | appear in the list of plugins in Gaim's |
|
3edb0348ba88
[gaim-migrate @ 11751]
Mark Doliner <markdoliner@pidgin.im>
parents:
10468
diff
changeset
|
160 | preferences window. |
| 10468 | 161 | */ |
|
10469
3edb0348ba88
[gaim-migrate @ 11751]
Mark Doliner <markdoliner@pidgin.im>
parents:
10468
diff
changeset
|
162 | NULL, /* This is a GList of plugin dependencies. In |
|
3edb0348ba88
[gaim-migrate @ 11751]
Mark Doliner <markdoliner@pidgin.im>
parents:
10468
diff
changeset
|
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
3edb0348ba88
[gaim-migrate @ 11751]
Mark Doliner <markdoliner@pidgin.im>
parents:
10468
diff
changeset
|
166 | value to NULL. |
| 10468 | 167 | */ |
|
10469
3edb0348ba88
[gaim-migrate @ 11751]
Mark Doliner <markdoliner@pidgin.im>
parents:
10468
diff
changeset
|
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
3edb0348ba88
[gaim-migrate @ 11751]
Mark Doliner <markdoliner@pidgin.im>
parents:
10468
diff
changeset
|
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
3edb0348ba88
[gaim-migrate @ 11751]
Mark Doliner <markdoliner@pidgin.im>
parents:
10468
diff
changeset
|
182 | 1.1, /* This is the version of your plugin. For |
|
3edb0348ba88
[gaim-migrate @ 11751]
Mark Doliner <markdoliner@pidgin.im>
parents:
10468
diff
changeset
|
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 | */ | |
|
13957
c6ca17e312aa
[gaim-migrate @ 16380]
Richard Laager <rlaager@pidgin.im>
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
3edb0348ba88
[gaim-migrate @ 11751]
Mark Doliner <markdoliner@pidgin.im>
parents:
10468
diff
changeset
|
203 | your attention. |
| 10468 | 204 | */ |
| 205 | ||
|
10469
3edb0348ba88
[gaim-migrate @ 11751]
Mark Doliner <markdoliner@pidgin.im>
parents:
10468
diff
changeset
|
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
3edb0348ba88
[gaim-migrate @ 11751]
Mark Doliner <markdoliner@pidgin.im>
parents:
10468
diff
changeset
|
212 | Returning TRUE will tell Gaim to continue |
| 10468 | 213 | loading your plugin, while FALSE will tell |
|
10469
3edb0348ba88
[gaim-migrate @ 11751]
Mark Doliner <markdoliner@pidgin.im>
parents:
10468
diff
changeset
|
214 | Gaim to stop trying to load it. |
| 10468 | 215 | */ |
| 216 | NULL, /* Same as above except it is called when | |
|
10469
3edb0348ba88
[gaim-migrate @ 11751]
Mark Doliner <markdoliner@pidgin.im>
parents:
10468
diff
changeset
|
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
3edb0348ba88
[gaim-migrate @ 11751]
Mark Doliner <markdoliner@pidgin.im>
parents:
10468
diff
changeset
|
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
3edb0348ba88
[gaim-migrate @ 11751]
Mark Doliner <markdoliner@pidgin.im>
parents:
10468
diff
changeset
|
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
3edb0348ba88
[gaim-migrate @ 11751]
Mark Doliner <markdoliner@pidgin.im>
parents:
10468
diff
changeset
|
268 | @c GAIM_INIT_PLUGIN is a macro that EVERY plugin MUST have. @c GAIM_INIT_PLUGIN |
|
3edb0348ba88
[gaim-migrate @ 11751]
Mark Doliner <markdoliner@pidgin.im>
parents:
10468
diff
changeset
|
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 | */ |