comparison mcabber/doc/HOWTO_modules.txt @ 1669:004739237999

Update modules howto
author Myhailo Danylenko <isbear@ukrpost.net>
date Mon, 18 Jan 2010 15:53:20 +0200
parents e3b93594ee6c
children b09f82f61745
comparison
equal deleted inserted replaced
1668:41c26b7d2890 1669:004739237999
26 I will not explain them all, there are too much of 26 I will not explain them all, there are too much of
27 them, but will provide description for those, provided 27 them, but will provide description for those, provided
28 especially for module writers. 28 especially for module writers.
29 29
30 -------------------------------------------------------- 30 --------------------------------------------------------
31 #include "commands.h" 31 #include <mcabber/commands.h>
32 32
33 void cmd_add (const char *name, const char *help, 33 void cmd_add (const char *name, const char *help,
34 guint flags1, guint flags2, 34 guint flags1, guint flags2,
35 void (*f)(char*), gpointer userdata); 35 void (*f)(char*), gpointer userdata);
36 void cmd_del (const char *name); 36 void cmd_del (const char *name);
51 void (*f) (char *commandline, gpointer userdata). 51 void (*f) (char *commandline, gpointer userdata).
52 - userdata is a pointer to data, transparently passed 52 - userdata is a pointer to data, transparently passed
53 to callback. See f description. 53 to callback. See f description.
54 54
55 -------------------------------------------------------- 55 --------------------------------------------------------
56 #include "compl.h" 56 #include <mcabber/compl.h>
57 57
58 guint compl_new_category (void); 58 guint compl_new_category (void);
59 void compl_del_category (guint id); 59 void compl_del_category (guint id);
60 60
61 void compl_add_category_word (guint categ, 61 void compl_add_category_word (guint categ,
84 of category by using gompl_get_category_list. If after 84 of category by using gompl_get_category_list. If after
85 execution dynlist is TRUE, you should free obtained 85 execution dynlist is TRUE, you should free obtained
86 list of words (both, words and list). 86 list of words (both, words and list).
87 87
88 -------------------------------------------------------- 88 --------------------------------------------------------
89 #include "hooks.h" 89 #include <mcabber/hooks.h>
90 90
91 typedef struct { 91 typedef struct {
92 const char *name; 92 const char *name;
93 const char *value; 93 const char *value;
94 } hk_arg_t; 94 } hk_arg_t;
151 - hook-post-connect (HOOK_INTERNAL) with no parameters 151 - hook-post-connect (HOOK_INTERNAL) with no parameters
152 - hook-pre-disconnect (HOOK_INTERNAL) with no 152 - hook-pre-disconnect (HOOK_INTERNAL) with no
153 parameters 153 parameters
154 154
155 -------------------------------------------------------- 155 --------------------------------------------------------
156 #include "xmpp_helper.h" 156 #include <mcabber/xmpp_helper.h>
157 157
158 void xmpp_add_feature (const char *xmlns); 158 void xmpp_add_feature (const char *xmlns);
159 void xmpp_del_feature (const char *xmlns); 159 void xmpp_del_feature (const char *xmlns);
160 -------------------------------------------------------- 160 --------------------------------------------------------
161 161
177 #include <glib.h> 177 #include <glib.h>
178 #include <gmodule.h> 178 #include <gmodule.h>
179 179
180 /* We will use scr_LogPrint mcabber function, 180 /* We will use scr_LogPrint mcabber function,
181 that does mcabber's messages output */ 181 that does mcabber's messages output */
182 #include "logprint.h" 182 #include <mcabber/logprint.h>
183 183
184 /* Print something on module loading */ 184 /* Print something on module loading */
185 const gchar* g_module_check_init (GModule *module) 185 const gchar* g_module_check_init (GModule *module)
186 { 186 {
187 scr_LogPrint (LPRINT_LOGNORM, "Hello, World!"); 187 scr_LogPrint (LPRINT_NORMAL, "Hello, World!");
188 return NULL; 188 return NULL;
189 } 189 }
190 190
191 /* ... and unloading */ 191 /* ... and unloading */
192 void g_module_unload (GModule *module) 192 void g_module_unload (GModule *module)
193 { 193 {
194 scr_LogPrint (LPRINT_LOGNORM, "Bye, World!"); 194 scr_LogPrint (LPRINT_NORMAL, "Bye, World!");
195 } 195 }
196 196
197 /* The End */ 197 /* The End */
198 -------------------------------------------------------- 198 --------------------------------------------------------
199 199
234 234
235 -------------------------------------------------------- 235 --------------------------------------------------------
236 #include <glib.h> 236 #include <glib.h>
237 #include <gmodule.h> 237 #include <gmodule.h>
238 238
239 #include "logprint.h" 239 #include <mcabber/logprint.h>
240 #include "commands.h" 240 #include <mcabber/commands.h>
241 241
242 /* Handler for command */ 242 /* Handler for command */
243 void do_hello (char *args) 243 void do_hello (char *args)
244 { 244 {
245 /* args contains command line with command 245 /* args contains command line with command
246 * name and any spaces after it stripped */ 246 * name and any spaces after it stripped */
247 scr_LogPrint (LPRINT_LOGNORM, "Hello, %s!", 247 scr_LogPrint (LPRINT_NORMAL, "Hello, %s!",
248 *args != '\0' ? args : "World"); 248 *args != '\0' ? args : "World");
249 } 249 }
250 250
251 /* Register command */ 251 /* Register command */
252 const gchar* g_module_check_init (GModule *module) 252 const gchar* g_module_check_init (GModule *module)
262 } 262 }
263 263
264 /* The End */ 264 /* The End */
265 -------------------------------------------------------- 265 --------------------------------------------------------
266 266
267 There we will need also config.h with defined MODULES_ENABLE
268 to satisfy ifdefs in commands.h. You can get one from mcabber
269 build tree, generated by configure or just provide your own:
270
271 --------------------------------------------------------
272 #ifndef LOCAL_CONFIG_H
273 #define LOCAL_CONFIG_H
274
275 #define MODULES_ENABLE 1
276
277 #endif
278 --------------------------------------------------------
279
280 Now, compile it and try to load and run /hello with some 267 Now, compile it and try to load and run /hello with some
281 arguments. 268 arguments.
282 269
283 Note, that we used one-argument version of command 270 Note, that we used one-argument version of command
284 handler, as we specified no userdata. 271 handler, as we specified no userdata.
287 274
288 Example: completion 275 Example: completion
289 276
290 ========================== 277 ==========================
291 278
292 Now le's investigate how to provide custom completion to 279 Now let's investigate how to provide custom completion to
293 your commands. You can as well use built-in completions, 280 your commands. You can as well use built-in completions,
294 their IDs are listed in compl.h. 281 their IDs are listed in compl.h.
295 282
296 -------------------------------------------------------- 283 --------------------------------------------------------
297 #include <glib.h> 284 #include <glib.h>
298 #include <gmodule.h> 285 #include <gmodule.h>
299 286
300 #include "logprint.h" 287 #include <mcabber/logprint.h>
301 #include "commands.h" 288 #include <mcabber/commands.h>
302 #include "compl.h" 289 #include <mcabber/compl.h>
303 290
304 static guint hello_cid = 0; 291 static guint hello_cid = 0;
305 292
306 /* hello command handler */ 293 /* hello command handler */
307 void do_hello (char *args) 294 void do_hello (char *args)
309 /* If argument is provided, add it to 296 /* If argument is provided, add it to
310 * completions list. */ 297 * completions list. */
311 if (hello_cid && *args != '\0') 298 if (hello_cid && *args != '\0')
312 compl_add_category_word (hello_cid, 299 compl_add_category_word (hello_cid,
313 args); 300 args);
314 scr_LogPrint (LPRINT_LOGNORM, "Hello, %s!", 301 scr_LogPrint (LPRINT_NORMAL, "Hello, %s!",
315 *args != '\0' ? args : "World"); 302 *args != '\0' ? args : "World");
316 } 303 }
317 304
318 /* Initialization */ 305 /* Initialization */
319 const gchar* g_module_check_init (GModule *module) 306 const gchar* g_module_check_init (GModule *module)
346 Now you can use completion for hello command. Note, that 333 Now you can use completion for hello command. Note, that
347 this code have some serious simplifications, made for 334 this code have some serious simplifications, made for
348 simplicity reasons. For now, compl_add_category_word 335 simplicity reasons. For now, compl_add_category_word
349 does not checks, if word already exists in completions 336 does not checks, if word already exists in completions
350 list (although it is marked as TODO, so, some day it 337 list (although it is marked as TODO, so, some day it
351 will), so, we should check it ourselves. Also, we should 338 will), so, we should check it ourselves.
352 check, that args contains only one word, or this will
353 confuse completion system, so, it will stop on this
354 completion.
355 339
356 ===================== 340 =====================
357 341
358 Example: hooks 342 Example: hooks
359 343
367 -------------------------------------------------------- 351 --------------------------------------------------------
368 #include <glib.h> 352 #include <glib.h>
369 #include <gmodule.h> 353 #include <gmodule.h>
370 #include <string.h> 354 #include <string.h>
371 355
372 #include "logprint.h" 356 #include <mcabber/logprint.h>
373 #include "commands.h" 357 #include <mcabber/commands.h>
374 #include "compl.h" 358 #include <mcabber/compl.h>
375 #include "hooks.h" 359 #include <mcabber/hooks.h>
376 #include "screen.h" 360 #include <mcabber/screen.h>
377 #include "settings.h" 361 #include <mcabber/settings.h>
378 362
379 static guint beep_cid = 0; 363 static guint beep_cid = 0;
380 364
381 /* Event handler */ 365 /* Event handler */
382 void beep_hh (guint32 hid, hk_arg_t *args, gpointer userdata) 366 void beep_hh (guint32 hid, hk_arg_t *args, gpointer userdata)
447 431
448 /* The End */ 432 /* The End */
449 -------------------------------------------------------- 433 --------------------------------------------------------
450 434
451 Note, that to compile this we also need to add loudmouth-1.0 435 Note, that to compile this we also need to add loudmouth-1.0
452 to pkg-config command line and to add -I. to compilation 436 to pkg-config command line, so, you will have something like
453 mode gcc command line (specify include directory with our
454 config.h as system include directory), so, you will have
455 something like
456 437
457 libtool --mode=compile gcc `pkg-config --cflags glib-2.0 \ 438 libtool --mode=compile gcc `pkg-config --cflags glib-2.0 \
458 gmodule-2.0 loudmouth-1.0` -I. -c beep.c 439 gmodule-2.0 loudmouth-1.0` -c beep.c
459 libtool --mode=link gcc -module -rpath /usr/lib/mcabber/ \ 440 libtool --mode=link gcc -module -rpath /usr/lib/mcabber/ \
460 `pkg-config --cflags glib-2.0 gmodule-2.0 loudmouth-1.0` \ 441 `pkg-config --cflags glib-2.0 gmodule-2.0` -o libbeep.la \
461 -o libbeep.la beep.lo 442 beep.lo
462 libtool --mode=install install libbeep.la \ 443 libtool --mode=install install libbeep.la \
463 /usr/lib/mcabber/libbeep.la 444 /usr/lib/mcabber/libbeep.la
464 445
465 If you use CMake (as do I), corresponding CMakeLists.txt 446 If you use CMake (as do I), corresponding CMakeLists.txt
466 snippet: 447 snippet:
467 448
468 -------------------------------------------------------- 449 --------------------------------------------------------
469 cmake_minimum_required(VERSION 2.6) 450 cmake_minimum_required(VERSION 2.6)
470 project(beep C) 451 project(beep C)
471 452
472 add_library(beep MODULE beep.c) 453 set(MCABBER_INCLUDE_DIR "/usr/include" CACHE FILEPATH
473 454 "Path to mcabber headers")
474 set(MCABBER_INCLUDE_DIR "${beep_SOURCE_DIR}/include"
475 CACHE FILEPATH "Path to mcabber headers")
476 455
477 find_package(PkgConfig REQUIRED) 456 find_package(PkgConfig REQUIRED)
478 pkg_check_modules(GLIB REQUIRED glib-2.0) 457 pkg_check_modules(GLIB REQUIRED glib-2.0)
479 pkg_check_modules(GMODULE REQUIRED gmodule-2.0) 458 pkg_check_modules(GMODULE REQUIRED gmodule-2.0)
480 pkg_check_modules(LM REQUIRED loudmouth-1.0) 459 pkg_check_modules(LM REQUIRED loudmouth-1.0)
460 # this one should be before any target definitions
461 link_directories(${GLIB_LIBRARY_DIRS}
462 ${GMODULE_LIBRARY_DIRS})
463
464 add_library(beep MODULE beep.c)
481 465
482 include_directories(SYSTEM ${GLIB_INCLUDE_DIRS} 466 include_directories(SYSTEM ${GLIB_INCLUDE_DIRS}
483 ${GMODULE_INCLUDE_DIRS} 467 ${GMODULE_INCLUDE_DIRS}
484 ${LM_INCLUDE_DIRS}) 468 ${LM_INCLUDE_DIRS}
469 ${MCABBER_INCLUDE_DIR})
485 target_link_libraries(beep ${GLIB_LIBRARIES} 470 target_link_libraries(beep ${GLIB_LIBRARIES}
486 ${GMODULE_LIBRARIES}) 471 ${GMODULE_LIBRARIES})
487 include_directories(${beep_SOURCE_DIR} 472 include_directories(${beep_SOURCE_DIR}
488 ${beep_BINARY_DIR} 473 ${beep_BINARY_DIR})
489 ${MCABBER_INCLUDE_DIR})
490 474
491 install(TARGETS beep DESTINATION lib/mcabber) 475 install(TARGETS beep DESTINATION lib/mcabber)
492 -------------------------------------------------------- 476 --------------------------------------------------------
493 477
494 ============== 478 ==============
496 Further 480 Further
497 481
498 ============== 482 ==============
499 483
500 As mcabber now uses glib mainloop, you can use glib's 484 As mcabber now uses glib mainloop, you can use glib's
501 event sources, for example, fifo reading can be easily 485 event sources, for example, fifo reading already uses
502 modularized with GIOChannels. 486 GIOChannels for non-blocking IO.
503 487
504 You can extend xmpp part of mcabber functionality by 488 You can extend xmpp part of mcabber functionality by
505 providing lm message handlers with high priority and 489 providing lm message handlers with high priority and
506 allowing unhandled by your handler messages be taken 490 allowing unhandled by your handler messages be taken
507 care by mcabber's handlers on normal priority level. 491 care by mcabber's handlers on normal priority level.
508 This is where you may need to modify set of advertised 492 This is where you may need to modify set of advertised
509 supported disco features. 493 supported disco features.
510 494
511 Many useful examples can be found in my mcabber-lua 495 Many useful examples can be found in my modules, that
512 module. 496 can be found at http://isbear.unixzone.org.ua/source.
513 497
514 If you think, that your module needs to change 498 If you think, that your module needs to change
515 something, hardcoded in current implementation - feel 499 something, hardcoded in current implementation - feel
516 free to mail me or join mcabber's MUC room and 500 free to mail me or join mcabber's MUC room and
517 discuss this - for now I have only implemented things, 501 discuss this - for now I have only implemented things,
518 that I found necessary for mcabber-lua module. 502 that I found necessary for written by me modules.
519 503
520 Also I am not native English speaker, so, if you find 504 Also I am not native English speaker, so, if you find
521 some errors or non-natural constructs in this howto, 505 some errors or non-natural constructs in this howto,
522 please, inform me (I will be glad, if you also provide 506 please, inform me (I will be glad, if you also provide
523 a more suitable version of text in question). 507 a more suitable version of text in question).
524 508
525 -- Myhailo Danylenko <isbear@ukrpost.net> 509 -- Myhailo Danylenko
526 -- Mon, 05 Oct 2009 00:00:00 +0300 510 -- mailto:isbear@ukrpost.net
527 511 -- xmpp:isbear@unixzone.org.ua
512 -- Mon, 18 Jan 2010 15:52:40 +0200
513