| 263 | == DBUS glib example == |
| 264 | To use DBUS glib library to listen to pidgin signals, things are little bit different from what you will do with Python. |
| 265 | |
| 266 | * First of all, you need to define marshaller functions for the signal handler.[[BR]]I.e., if you want to listen to signal '''''!ReceivedImMsg''''', the first thing to do is to find out the correct parameters associated with the signal. Since there is no any document specifying each Pidgin signal's parameter format, one good way to find out the secret is to use dbus-monitor. Start the dbus-monitor like |
| 267 | {{{ |
| 268 | $dbus-monitor type=signal interface="im.pidgin.purple.PurpleInterface" |
| 269 | }}} |
| 270 | |
| 271 | And then ask your buddy to send you some IM messages. The dbus-monitor will print out something like: |
| 272 | {{{ |
| 273 | signal sender=:1.21 -> dest=(null destination) path=/im/pidgin/purple/PurpleObject; interface=im.pidgin.purple.PurpleInterface; member=ReceivedImMsg |
| 274 | uint32 1097 |
| 275 | string "mybuddy@hotmail.com" |
| 276 | string "<FONT FACE="Times"><FONT COLOR="#000000">Hi!</FONT></FONT>" |
| 277 | uint32 8728 |
| 278 | uint32 0 |
| 279 | }}} |
| 280 | |
| 281 | Now you know that the parameters associated with signal '''''!ReceivedImMsg''''' are: |
| 282 | {{{ |
| 283 | UINT32, |
| 284 | STRING, |
| 285 | STRING, |
| 286 | UINT32, |
| 287 | UINT32 |
| 288 | }}} |
| 289 | |
| 290 | Then we can create file '''marshal.list''' with the one line marshaller function definition: |
| 291 | {{{ |
| 292 | VOID:UINT,STRING,STRING,UINT,UINT |
| 293 | }}} |
| 294 | |
| 295 | * Second, generate '''marshal.h''' and '''marshal.c'''[[BR]]After create your own file '''marshal.list''', you can then use tool '''glib-genmarshal''' to generate '''marshal.h''' and '''marshal.c''' in the following way: |
| 296 | {{{ |
| 297 | $glib-genmarshal --header --prefix=marshal marshal.list > marshal.h |
| 298 | $glib-genmarshal --body --prefix=marshal marshal.list > marshal.c |
| 299 | }}} |
| 300 | |
| 301 | * Third, write your own signal handler '''pidgin_dbus_signal_hndl.c''': |
| 302 | {{{ |
| 303 | #include <glib.h> |
| 304 | #include <glib-object.h> |
| 305 | #include <dbus/dbus.h> |
| 306 | #include <dbus/dbus-glib.h> |
| 307 | |
| 308 | #include "marshal.h" /* The file generated from marshal.list via tool glib-genmarshal */ |
| 309 | |
| 310 | /* pidgin dbus station name */ |
| 311 | #define DBUS_SERVICE_PURPLE "im.pidgin.purple.PurpleService" |
| 312 | #define DBUS_PATH_PURPLE "/im/pidgin/purple/PurpleObject" |
| 313 | #define DBUS_INTERFACE_PURPLE "im.pidgin.purple.PurpleInterface" |
| 314 | |
| 315 | /* global dbus instance */ |
| 316 | DBusGConnection *bus; |
| 317 | DBusGProxy *purple_proxy; |
| 318 | |
| 319 | |
| 320 | /* Main event loop */ |
| 321 | GMainLoop *loop = NULL; |
| 322 | |
| 323 | /* Signal callback handling routing */ |
| 324 | void received_im_msg_cb (DBusGProxy *purple_proxy, unsigned int account_id, |
| 325 | const char *sender, const char *message, |
| 326 | unsigned int conv_id, unsigned int flags, |
| 327 | gpointer user_data) |
| 328 | { |
| 329 | g_print("Account %d receives msg \"%s\" from %s\n", |
| 330 | account_id, message, sender); |
| 331 | } |
| 332 | |
| 333 | /* |
| 334 | * The main process, loop waiting for any signals |
| 335 | */ |
| 336 | int main (int argc, char **argv) |
| 337 | { |
| 338 | GError *error = NULL; |
| 339 | |
| 340 | g_type_init (); |
| 341 | |
| 342 | /* Get the bus */ |
| 343 | bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error); |
| 344 | if (bus == NULL) { |
| 345 | g_printerr("Failed to open connection to bus: %s", error->message); |
| 346 | g_error_free(error); |
| 347 | return -1; |
| 348 | } |
| 349 | |
| 350 | /* Create a proxy object for the bus driver */ |
| 351 | purple_proxy = dbus_g_proxy_new_for_name (bus, |
| 352 | DBUS_SERVICE_PURPLE, |
| 353 | DBUS_PATH_PURPLE, |
| 354 | DBUS_INTERFACE_PURPLE); |
| 355 | |
| 356 | if (!purple_proxy) { |
| 357 | g_printerr("Couldn't connect to the Purple Service: %s", error->message); |
| 358 | g_error_free(error); |
| 359 | return -1; |
| 360 | } |
| 361 | |
| 362 | /* Create the main loop instance */ |
| 363 | loop = g_main_loop_new (NULL, FALSE); |
| 364 | |
| 365 | /* Register dbus signal marshaller */ |
| 366 | dbus_g_object_register_marshaller(marshal_VOID__UINT_STRING_STRING_UINT_UINT, |
| 367 | G_TYPE_NONE, G_TYPE_UINT, G_TYPE_STRING, |
| 368 | G_TYPE_STRING, G_TYPE_UINT, G_TYPE_UINT, |
| 369 | G_TYPE_INVALID); |
| 370 | |
| 371 | /* Add the signal to the proxy */ |
| 372 | dbus_g_proxy_add_signal(purple_proxy, "ReceivedImMsg", |
| 373 | G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING, |
| 374 | G_TYPE_UINT, G_TYPE_UINT, G_TYPE_INVALID); |
| 375 | |
| 376 | /* Connect the signal handler to the proxy */ |
| 377 | dbus_g_proxy_connect_signal(purple_proxy, "ReceivedImMsg", |
| 378 | G_CALLBACK(received_im_msg_cb), bus, NULL); |
| 379 | |
| 380 | /* Main loop */ |
| 381 | g_main_loop_run (loop); |
| 382 | |
| 383 | return 0; |
| 384 | } |
| 385 | }}} |
| 386 | |
| 387 | Then compile both '''marshal.c''' and '''pidgin_dbus_signal_hndl.c''': |
| 388 | {{{ |
| 389 | $ gcc -MMD -Wall -ggdb -O `pkg-config --cflags dbus-1 glib-2.0 dbus-glib-1` `pkg-config --libs dbus-1 glib-2.0 dbus-glib-1` marshal.c pidgin_dbus_signal_hndl.c -o sighndl |
| 390 | }}} |
| 391 | |
| 392 | And then run '''sighndl''': |
| 393 | {{{ |
| 394 | ./sighndl |
| 395 | }}} |
| 396 | When your buddy sends you any IM message, if everything goes right, your program will print out something like |
| 397 | {{{ |
| 398 | Account 1097 receives msg "<FONT FACE="Times"><FONT COLOR="#000000">Hi</FONT></FONT>" from mybuddy |
| 399 | }}} |