GTK מכיל, בגירסאותיו החדשות, תמיכה מובנית מצויינת בכיווניות (ימין/שמאל). הכיווניות של כל פסקה נקבעת ע"י האות האלפבתית הראשונה בה. האלגוריתם פועל היטב, וממקם את הנקודות וסימני הפיסוק כמו שצריך. (בניגוד ליישור פשוט)


בברירת מחדל, Gaim - תוכנת מסרים מיידיים מוכרת - ממקמת את שם המשתמש בתחילת כל הודעה שהוא שולח. מאחר ושמות משתמש ברשתות המסרים נוטים להיות באנגלית, לא נדיר לראות את המצב הבא:

הפתרון המתבקש, אם כן - לשבור את השורה בין שם המשתמש להודעה.
מומלץ להתקין את החבילות doxygen ו-graphviz, ולהוריד את קוד המקור של gaim. נפרוש אותו בצורה הרגילה, ונריץ את הפקודות הבאות:
$ tar -jxf gaim-src-1.3.1.tar.bz2 $ cd gaim-src-1.3.1/ $ ./configure $ make docs
השורה האחרונה תיצור באמצעות doxygen ו-graphviz את תוכן התיקייה doc/html, שתכיל דוקומנטציה מלאה על ה-API של Gaim. שלב זה אינו הכרחי, כמובן.
התיקייה plugins מכילה דוגמאות ל-plugins, כולל את אלו שמופצים בברירת מחדל עם gaim, וגם קובץ Makefile שמשמש לקומפילציה של plugins. כדי לקמפל את הפלאגין newline, יש למקמו בתיקייה זו ואז להריץ את הפקודה הבאה:
$ make newline.so
לאחר מכן ניתן למקם את הפלאגין המקומפל בתיקיית המשתמש ~/.gaim/plugins או בתיקיית המערכת /usr/lib/gaim לשימוש כל המשתמשים.
הפעולה של הפלאגין טריוויאלית, ורובו נכתב ע"י ניחוש ולקיחת דוגמאות מפלאגינים אחרים.
/* * newline plugin for gaim * version 0.2 * * ... (GPL notice) ... * */ #include "internal.h" #include "conversation.h" #include "plugin.h" #include "version.h"
הפונקציה הבאה עושה את כל המלאכה. היא מקבלת את ההודעה (מלל ההודעה עצמו, ללא שם המשתמש או עיצוב), ומוסיפה בהתחלתה את סימן ה-HTML שמוסיף שורה, <br>. שימו לב שהפונקציה יוצרת עותק חדש של ההודעה ומשחררת את הישן - זאת ע"פ דרישה שמצויינת ב-API.
static gboolean add_msg_newline(GaimAccount *account, GaimConversation *conv,
char **message)
{
char * newmsg = NULL;
newmsg = g_strdup_printf("<br>%s", *message);
free(*message);
*message = newmsg;
return FALSE;
}
הפונקציה הבאה נקראת בעת טעינת הפלאגין. היא משתמשת ב-API של Gaim כדי להפעיל את פונקציית שבירת-השורה שלנו בשתי הזדמנויות: כשמציגים הודעה שאנחנו שלחנו, וכשמציגים הודעה שקיבלנו. האירועים displaying-im-msg ו-receiving-im-msg מופעלים בשלב העיבוד המוקדם של ההודעה, לפני שהיא מעוצבת לתצוגה על המסך.
static gboolean plugin_load(GaimPlugin *plugin)
{
void *conv_handle = gaim_conversations_get_handle();
gaim_signal_connect(conv_handle, "displaying-im-msg", plugin,
GAIM_CALLBACK(add_msg_newline), NULL);
gaim_signal_connect(conv_handle, "receiving-im-msg", plugin,
GAIM_CALLBACK(add_msg_newline), NULL);
return TRUE;
}
באופן דומה, הפונקציה הבאה נקראת בעת הסרת הפלאגין מהזכרון, ומנתקת את האירועים מהפונקציה שלנו.
static gboolean plugin_unload(GaimPlugin *plugin)
{
void *conv_handle = gaim_conversations_get_handle();
gaim_signal_disconnect(conv_handle, "displaying-chat-msg", plugin,
GAIM_CALLBACK(add_msg_newline));
gaim_signal_disconnect(conv_handle, "receiving-chat-msg", plugin,
GAIM_CALLBACK(add_msg_newline));
return TRUE;
}
הבלוק הבא מכיל אינפורמציה נחוצה על הפלאגין.
static GaimPluginInfo info =
{
GAIM_PLUGIN_MAGIC,
GAIM_MAJOR_VERSION,
GAIM_MINOR_VERSION,
GAIM_PLUGIN_STANDARD, /**< type */
NULL, /**< ui_requirement */
0, /**< flags */
NULL, /**< dependencies */
GAIM_PRIORITY_DEFAULT, /**< priority */
NULL, /**< id */
N_("Newline"), /**< name */
"0.2", /**< version */
/** summary */
N_("Adds a newline before messages."),
/** description */
N_("Adds a newline before messages, for better bidi compatibility."),
"Ohad Lutzky <ohad_l@yahoo.com>", /**< author */
"http://lutzky.homelinux.net/~tactless", /**< homepage */
plugin_load, /**< load */
plugin_unload, /**< unload */
NULL, /**< destroy */
NULL, /**< ui_info */
NULL, /**< extra_info */
NULL,
NULL
};
הפונקציה הבאה דרושה, ומשמשת לטיפול מיוחד בעת הטעינה הראשונה של הפלאגין. אין לנו צורך בכך בפלאגין זה, ולכן השארנו אותה ריקה.
static void
init_plugin(GaimPlugin *plugin)
{
}
ולאחר מאקרו קסום של Gaim, סיימנו את כתיבת הפלאגין.
GAIM_INIT_PLUGIN(simple, init_plugin, info)
pkg-config למטרה זו.