pidgin  2.13.0
About: Pidgin is a chat program (multi-protocol instant messaging client) which lets you log in to accounts on multiple chat networks simultaneously (old name "gaim").
  Fossies Dox: pidgin-2.13.0.tar.gz  ("inofficial" and yet experimental doxygen-generated source code documentation)  

gntgf.c
Go to the documentation of this file.
1 
22 #include "internal.h"
23 
24 #define PLUGIN_STATIC_NAME GntGf
25 
26 #define PREFS_PREFIX "/plugins/gnt/gntgf"
27 #define PREFS_EVENT PREFS_PREFIX "/events"
28 #define PREFS_EVENT_SIGNONF PREFS_EVENT "/signonf"
29 #define PREFS_EVENT_IM_MSG PREFS_EVENT "/immsg"
30 #define PREFS_EVENT_CHAT_MSG PREFS_EVENT "/chatmsg"
31 #define PREFS_EVENT_CHAT_NICK PREFS_EVENT "/chatnick"
32 #define PREFS_BEEP PREFS_PREFIX "/beep"
33 
34 #define MAX_COLS 3
35 
36 #ifdef HAVE_X11
37 #define PREFS_URGENT PREFS_PREFIX "/urgent"
38 
39 #include <X11/Xlib.h>
40 #include <X11/Xutil.h>
41 #endif
42 
43 #include <glib.h>
44 
45 #include <plugin.h>
46 #include <version.h>
47 #include <blist.h>
48 #include <conversation.h>
49 #include <debug.h>
50 #include <eventloop.h>
51 #include <util.h>
52 
53 #include <gnt.h>
54 #include <gntbox.h>
55 #include <gntbutton.h>
56 #include <gntcheckbox.h>
57 #include <gntlabel.h>
58 #include <gnttree.h>
59 
60 #include "gntplugin.h"
61 #include "gntconv.h"
62 
63 typedef struct
64 {
66  int timer;
67  int column;
68 } GntToast;
69 
70 static GList *toasters;
71 static int gpsy[MAX_COLS];
72 static int gpsw[MAX_COLS];
73 
74 static void
76 {
77  toasters = g_list_remove(toasters, toast);
78  gnt_widget_destroy(toast->window);
80  g_free(toast);
81 }
82 
83 static gboolean
85 {
86  GList *iter;
87  int h;
88  int col;
89  int nwin[MAX_COLS];
90 
91  gnt_widget_get_size(toast->window, NULL, &h);
92  gpsy[toast->column] -= h;
93  col = toast->column;
94 
95  memset(&nwin, 0, sizeof(nwin));
96  destroy_toaster(toast);
97 
98  for (iter = toasters; iter; iter = iter->next)
99  {
100  int x, y;
101  toast = iter->data;
102  nwin[toast->column]++;
103  if (toast->column != col) continue;
104  gnt_widget_get_position(toast->window, &x, &y);
105  y += h;
106  gnt_screen_move_widget(toast->window, x, y);
107  }
108 
109  if (nwin[col] == 0)
110  gpsw[col] = 0;
111 
112  return FALSE;
113 }
114 
115 #ifdef HAVE_X11
116 static int
117 error_handler(Display *dpy, XErrorEvent *error)
118 {
119  char buffer[1024];
120  XGetErrorText(dpy, error->error_code, buffer, sizeof(buffer));
121  purple_debug_error("gntgf", "Could not set urgent to the window: %s.\n", buffer);
122  return 0;
123 }
124 
125 static void
126 urgent(void)
127 {
128  /* This is from deryni/tuomov's urgent_test.c */
129  Display *dpy;
130  Window id;
131  const char *ids;
132  XWMHints *hints;
133 
134  ids = getenv("WINDOWID");
135  if (ids == NULL)
136  return;
137 
138  id = atoi(ids);
139 
140  dpy = XOpenDisplay(NULL);
141  if (dpy == NULL)
142  return;
143 
144  XSetErrorHandler(error_handler);
145  hints = XGetWMHints(dpy, id);
146  if (hints) {
147  hints->flags|=XUrgencyHint;
148  XSetWMHints(dpy, id, hints);
149  XFree(hints);
150  }
151  XSetErrorHandler(NULL);
152 
153  XFlush(dpy);
154  XCloseDisplay(dpy);
155 }
156 #endif
157 
158 static void
159 notify(PurpleConversation *conv, const char *fmt, ...)
160 {
161  GntWidget *window;
162  GntToast *toast;
163  char *str;
164  int h, w, i;
165  va_list args;
166 
168  beep();
169 
170  if (conv != NULL) {
171  FinchConv *fc = conv->ui_data;
172  if (gnt_widget_has_focus(fc->window))
173  return;
174  }
175 
176 #ifdef HAVE_X11
177  if (purple_prefs_get_bool(PREFS_URGENT))
178  urgent();
179 #endif
180 
184 
185  va_start(args, fmt);
186  str = g_strdup_vprintf(fmt, args);
187  va_end(args);
188 
191 
192  g_free(str);
194  gnt_widget_get_size(window, &w, &h);
195  for (i = 0; i < MAX_COLS && gpsy[i] + h >= getmaxy(stdscr) ; ++i)
196  ;
197  if (i >= MAX_COLS) {
198  purple_debug_warning("GntGf", "Dude, that's way too many popups\n");
200  return;
201  }
202 
203  toast = g_new0(GntToast, 1);
204  toast->window = window;
205  toast->column = i;
206  gpsy[i] += h;
207  if (w > gpsw[i]) {
208  if (i == 0)
209  gpsw[i] = w;
210  else
211  gpsw[i] = gpsw[i - 1] + w + 1;
212  }
213 
214  if (i == 0 || (w + gpsw[i - 1] >= getmaxx(stdscr))) {
215  /* if it's going to be too far left, overlap. */
216  gnt_widget_set_position(window, getmaxx(stdscr) - w - 1,
217  getmaxy(stdscr) - gpsy[i] - 1);
218  } else {
219  gnt_widget_set_position(window, getmaxx(stdscr) - gpsw[i - 1] - w - 1,
220  getmaxy(stdscr) - gpsy[i] - 1);
221  }
223 
224  toast->timer = purple_timeout_add_seconds(4, (GSourceFunc)remove_toaster, toast);
225  toasters = g_list_prepend(toasters, toast);
226 }
227 
228 static void
229 buddy_signed_on(PurpleBuddy *buddy, gpointer null)
230 {
232  notify(NULL, _("%s just signed on"), purple_buddy_get_alias(buddy));
233 }
234 
235 static void
236 buddy_signed_off(PurpleBuddy *buddy, gpointer null)
237 {
239  notify(NULL, _("%s just signed off"), purple_buddy_get_alias(buddy));
240 }
241 
242 static void
243 received_im_msg(PurpleAccount *account, const char *sender, const char *msg,
244  PurpleConversation *conv, PurpleMessageFlags flags, gpointer null)
245 {
247  notify(conv, _("%s sent you a message"), sender);
248 }
249 
250 static void
251 received_chat_msg(PurpleAccount *account, const char *sender, const char *msg,
252  PurpleConversation *conv, PurpleMessageFlags flags, gpointer null)
253 {
254  const char *nick;
255 
257  return;
258 
259  nick = PURPLE_CONV_CHAT(conv)->nick;
260 
261  if (g_utf8_collate(sender, nick) == 0)
262  return;
263 
265  (purple_utf8_has_word(msg, nick)))
266  notify(conv, _("%s said your nick in %s"), sender, purple_conversation_get_name(conv));
268  notify(conv, _("%s sent a message in %s"), sender, purple_conversation_get_name(conv));
269 }
270 
271 static gboolean
273 {
274  purple_signal_connect(purple_blist_get_handle(), "buddy-signed-on", plugin,
276  purple_signal_connect(purple_blist_get_handle(), "buddy-signed-off", plugin,
278  purple_signal_connect(purple_conversations_get_handle(), "received-im-msg", plugin,
280  purple_signal_connect(purple_conversations_get_handle(), "received-chat-msg", plugin,
282 
283  memset(&gpsy, 0, sizeof(gpsy));
284  memset(&gpsw, 0, sizeof(gpsw));
285 
286  return TRUE;
287 }
288 
289 static gboolean
291 {
292  while (toasters)
293  {
294  GntToast *toast = toasters->data;
295  destroy_toaster(toast);
296  }
297  return TRUE;
298 }
299 
300 static struct
301 {
302  char *pref;
303  char *display;
304 } prefs[] =
305 {
306  {PREFS_EVENT_SIGNONF, N_("Buddy signs on/off")},
307  {PREFS_EVENT_IM_MSG, N_("You receive an IM")},
308  {PREFS_EVENT_CHAT_MSG, N_("Someone speaks in a chat")},
309  {PREFS_EVENT_CHAT_NICK, N_("Someone says your name in a chat")},
310  {NULL, NULL}
311 };
312 
313 static void
314 pref_toggled(GntTree *tree, char *key, gpointer null)
315 {
317 }
318 
319 static void
321 {
323 }
324 
325 static GntWidget *
327 {
328  GntWidget *window, *tree, *check;
329  int i;
330 
335 
337  /* Translators: "toaster" here means "pop-up". */
338  gnt_label_new(_("Notify with a toaster when")));
339 
340  tree = gnt_tree_new();
342 
343  for (i = 0; prefs[i].pref; i++)
344  {
349  }
351  g_signal_connect(G_OBJECT(tree), "toggled", G_CALLBACK(pref_toggled), NULL);
352 
353  check = gnt_check_box_new(_("Beep too!"));
355  g_signal_connect(G_OBJECT(check), "toggled", G_CALLBACK(toggle_option), PREFS_BEEP);
357 
358 #ifdef HAVE_X11
359  check = gnt_check_box_new(_("Set URGENT for the terminal window."));
361  g_signal_connect(G_OBJECT(check), "toggled", G_CALLBACK(toggle_option), PREFS_URGENT);
363 #endif
364 
365  return window;
366 }
367 
369 {
375  0,
376  NULL,
378  "gntgf",
379  N_("GntGf"),
380  DISPLAY_VERSION,
381  /* Translators: "toaster" here means "pop-up". */
382  N_("Toaster plugin"),
383  /* Translators: "toaster" here means "pop-up". */
384  N_("Toaster plugin"),
385  "Sadrul H Chowdhury <sadrul@users.sourceforge.net>",
387  plugin_load,
389  NULL,
390  config_frame,
391  NULL,
392  NULL,
393  NULL,
394 
395  /* padding */
396  NULL,
397  NULL,
398  NULL,
399  NULL
400 };
401 
402 static void
404 {
405  purple_prefs_add_none("/plugins");
406  purple_prefs_add_none("/plugins/gnt");
407 
408  purple_prefs_add_none("/plugins/gnt/gntgf");
410 
415 
417 #ifdef HAVE_X11
418  purple_prefs_add_bool(PREFS_URGENT, FALSE);
419 #endif
420 }
421 
dbus-analyze-signals.args
args
Definition: dbus-analyze-signals.py:37
check
static int check
Definition: filectl.c:29
plugin_load
static gboolean plugin_load(PurplePlugin *plugin)
Definition: gntgf.c:272
GNT_WIDGET_NO_BORDER
Definition: gntwidget.h:59
_PurpleConversation::ui_data
void * ui_data
Definition: conversation.h:361
pref
char * pref
Definition: gntgf.c:302
pref_toggled
static void pref_toggled(GntTree *tree, char *key, gpointer null)
Definition: gntgf.c:314
_FinchConv::window
GntWidget * window
Definition: gntconv.h:56
PURPLE_WEBSITE
#define PURPLE_WEBSITE
Definition: internal.h:196
destroy_toaster
static void destroy_toaster(GntToast *toast)
Definition: gntgf.c:75
gnt_box_set_pad
void gnt_box_set_pad(GntBox *box, int pad)
Definition: gntbox.c:695
account
static PurpleAccount * account
Definition: raw.c:45
purple_conversations_get_handle
void * purple_conversations_get_handle(void)
Definition: conversation.c:2343
gnt_widget_get_size
void gnt_widget_get_size(GntWidget *wid, int *width, int *height)
Definition: gntwidget.c:464
purple_prefs_add_bool
void purple_prefs_add_bool(const char *name, gboolean value)
Definition: prefs.c:646
FINCH_PLUGIN_TYPE
#define FINCH_PLUGIN_TYPE
Definition: gntplugin.h:45
N_
#define N_(String)
Definition: internal.h:59
PREFS_EVENT_CHAT_MSG
#define PREFS_EVENT_CHAT_MSG
Definition: gntgf.c:30
gpsw
static int gpsw[3]
Definition: gntgf.c:72
PURPLE_INIT_PLUGIN
#define PURPLE_INIT_PLUGIN(pluginname, initfunc, plugininfo)
Definition: plugin.h:222
gntbox.h
gnt_tree_get_choice
gboolean gnt_tree_get_choice(GntTree *tree, void *key)
Definition: gnttree.c:1624
PREFS_EVENT
#define PREFS_EVENT
Definition: gntgf.c:27
flags
SectionFlags flags
Definition: themeedit-icon.c:97
notify
static void notify(PurpleConversation *conv, const char *fmt,...)
Definition: gntgf.c:159
GntToast::column
int column
Definition: gntgf.c:67
gnt_label_new
GntWidget * gnt_label_new(const char *text)
Definition: gntlabel.c:186
purple_signal_connect
gulong purple_signal_connect(void *instance, const char *signal, void *handle, PurpleCallback func, void *data)
Definition: signals.c:305
toggle_option
static void toggle_option(GntCheckBox *check, gpointer str)
Definition: gntgf.c:320
_GntWidget
Definition: gntwidget.h:98
gnt.h
_GntCheckBox
Definition: gntcheckbox.h:50
purple_debug_error
void purple_debug_error(const char *category, const char *format,...)
Definition: debug.c:145
purple_blist_get_handle
void * purple_blist_get_handle(void)
Definition: blist.c:3122
window
GntWidget * window
Definition: gntcertmgr.c:45
gnt_tree_new
GntWidget * gnt_tree_new()
Definition: gnttree.c:1194
gnt_vbox_new
#define gnt_vbox_new(homo)
Definition: gntbox.h:96
PREFS_EVENT_IM_MSG
#define PREFS_EVENT_IM_MSG
Definition: gntgf.c:29
purple_timeout_add_seconds
guint purple_timeout_add_seconds(guint interval, GSourceFunc function, gpointer data)
Definition: eventloop.c:40
plugin.h
_
void boot_DynaLoader _((pTHX_ CV *cv))
purple_conversation_get_name
const char * purple_conversation_get_name(const PurpleConversation *conv)
Definition: conversation.c:795
GNT_BOX
#define GNT_BOX(obj)
Definition: gntbox.h:34
blist.h
purple_utf8_has_word
gboolean purple_utf8_has_word(const char *haystack, const char *needle)
gnt_box_add_widget
void gnt_box_add_widget(GntBox *b, GntWidget *widget)
Definition: gntbox.c:674
version.h
GNT_ALIGN_MID
Definition: gntbox.h:49
GntToast::timer
int timer
Definition: gntgf.c:66
plugin_unload
static gboolean plugin_unload(PurplePlugin *plugin)
Definition: gntgf.c:290
PREFS_BEEP
#define PREFS_BEEP
Definition: gntgf.c:32
purple_prefs_set_bool
void purple_prefs_set_bool(const char *name, gboolean value)
Definition: prefs.c:898
config_frame
static GntWidget * config_frame(void)
Definition: gntgf.c:326
gnt_widget_set_position
void gnt_widget_set_position(GntWidget *wid, int x, int y)
Definition: gntwidget.c:440
str
static char str[256]
Definition: util.c:28
eventloop.h
_PurplePlugin
Definition: plugin.h:151
gntlabel.h
PURPLE_MESSAGE_WHISPER
Definition: conversation.h:120
PurpleMessageFlags
PurpleMessageFlags
Definition: conversation.h:105
gnt_tree_set_choice
void gnt_tree_set_choice(GntTree *tree, void *key, gboolean set)
Definition: gnttree.c:1612
NULL
#define NULL
Definition: getopt1.c:52
_GntTree
Definition: gnttree.h:57
purple_timeout_remove
gboolean purple_timeout_remove(guint tag)
Definition: eventloop.c:51
GNT_WIDGET_UNSET_FLAGS
#define GNT_WIDGET_UNSET_FLAGS(obj, flags)
Definition: gntwidget.h:45
GNT_TREE
#define GNT_TREE(obj)
Definition: gnttree.h:37
GNT_WIDGET_TRANSIENT
Definition: gntwidget.h:67
GNT_CHECK_BOX
#define GNT_CHECK_BOX(obj)
Definition: gntcheckbox.h:36
gnt_check_box_set_checked
void gnt_check_box_set_checked(GntCheckBox *box, gboolean set)
Definition: gntcheckbox.c:164
gnt_check_box_new
GntWidget * gnt_check_box_new(const char *text)
Definition: gntcheckbox.c:154
PURPLE_CALLBACK
#define PURPLE_CALLBACK(func)
Definition: signals.h:32
GNT_WIDGET_SET_FLAGS
#define GNT_WIDGET_SET_FLAGS(obj, flags)
Definition: gntwidget.h:44
gnt_widget_size_request
void gnt_widget_size_request(GntWidget *widget)
Definition: gntwidget.c:458
PURPLE_CONV_CHAT
PurpleConvIm * PURPLE_CONV_CHAT(const PurpleConversation *conversation)
PREFS_EVENT_SIGNONF
#define PREFS_EVENT_SIGNONF
Definition: gntgf.c:28
gnt_check_box_get_checked
gboolean gnt_check_box_get_checked(GntCheckBox *box)
Definition: gntcheckbox.c:173
gntbutton.h
toasters
static GList * toasters
Definition: gntgf.c:70
gnt_widget_get_position
void gnt_widget_get_position(GntWidget *wid, int *x, int *y)
Definition: gntwidget.c:449
TRUE
#define TRUE
Definition: protobuf-c.c:56
_PurpleAccount
Definition: account.h:169
GntToast
Definition: gntgf.c:63
gnt_tree_add_choice
GntTreeRow * gnt_tree_add_choice(GntTree *tree, void *key, GntTreeRow *row, void *parent, void *bigbro)
Definition: gnttree.c:1584
FALSE
#define FALSE
Definition: protobuf-c.c:57
purple_buddy_get_alias
const char * purple_buddy_get_alias(PurpleBuddy *buddy)
Definition: blist.c:2348
PREFS_EVENT_CHAT_NICK
#define PREFS_EVENT_CHAT_NICK
Definition: gntgf.c:31
PURPLE_PLUGIN_MAGIC
#define PURPLE_PLUGIN_MAGIC
Definition: plugin.h:71
gnt_label_new_with_format
GntWidget * gnt_label_new_with_format(const char *text, GntTextFormatFlags flags)
Definition: gntlabel.c:191
MAX_COLS
#define MAX_COLS
Definition: gntgf.c:34
GntToast::window
GntWidget * window
Definition: gntgf.c:65
gpsy
static int gpsy[3]
Definition: gntgf.c:71
display
char * display
Definition: gntgf.c:303
purple_prefs_add_none
void purple_prefs_add_none(const char *name)
Definition: prefs.c:638
conversation.h
gntplugin.h
purple_prefs_get_bool
gboolean purple_prefs_get_bool(const char *name)
Definition: prefs.c:1111
GNT_TEXT_FLAG_HIGHLIGHT
Definition: gnttextview.h:75
gnt_screen_move_widget
void gnt_screen_move_widget(GntWidget *widget, int x, int y)
Definition: gntmain.c:638
gntconv.h
tree
GntWidget * tree
Definition: gntcertmgr.c:46
gnt_widget_destroy
void gnt_widget_destroy(GntWidget *obj)
Definition: gntwidget.c:312
PURPLE_MAJOR_VERSION
#define PURPLE_MAJOR_VERSION
Definition: version.h:28
info
static PurplePluginInfo info
Definition: gntgf.c:368
gnt_widget_draw
void gnt_widget_draw(GntWidget *widget)
Definition: gntwidget.c:335
received_chat_msg
static void received_chat_msg(PurpleAccount *account, const char *sender, const char *msg, PurpleConversation *conv, PurpleMessageFlags flags, gpointer null)
Definition: gntgf.c:251
gnt_tree_set_col_width
void gnt_tree_set_col_width(GntTree *tree, int col, int width)
Definition: gnttree.c:1748
_PurplePluginInfo
Definition: plugin.h:78
init_plugin
static void init_plugin(PurplePlugin *plugin)
Definition: gntgf.c:403
gntcheckbox.h
error
const char * error
Definition: auth_scram.c:51
gnt_widget_has_focus
gboolean gnt_widget_has_focus(GntWidget *widget)
Definition: gntmain.c:572
_PurpleConversation
Definition: conversation.h:338
remove_toaster
static gboolean remove_toaster(GntToast *toast)
Definition: gntgf.c:84
PURPLE_MINOR_VERSION
#define PURPLE_MINOR_VERSION
Definition: version.h:30
received_im_msg
static void received_im_msg(PurpleAccount *account, const char *sender, const char *msg, PurpleConversation *conv, PurpleMessageFlags flags, gpointer null)
Definition: gntgf.c:243
PURPLE_PLUGIN_STANDARD
Definition: plugin.h:59
PLUGIN_STATIC_NAME
#define PLUGIN_STATIC_NAME
Definition: gntgf.c:24
buddy_signed_off
static void buddy_signed_off(PurpleBuddy *buddy, gpointer null)
Definition: gntgf.c:236
gnttree.h
gnt_tree_create_row
GntTreeRow * gnt_tree_create_row(GntTree *tree,...)
Definition: gnttree.c:1728
util.h
getenv
char * getenv()
_PurpleBuddy
Definition: blist.h:138
prefs
static struct @40 prefs[]
buddy_signed_on
static void buddy_signed_on(PurpleBuddy *buddy, gpointer null)
Definition: gntgf.c:229
gnt_box_set_fill
void gnt_box_set_fill(GntBox *box, gboolean fill)
Definition: gntbox.c:849
_FinchConv
Definition: gntconv.h:51
gnt_box_set_alignment
void gnt_box_set_alignment(GntBox *box, GntAlignment alignment)
Definition: gntbox.c:775
purple_debug_warning
void purple_debug_warning(const char *category, const char *format,...)
Definition: debug.c:133
PURPLE_PRIORITY_DEFAULT
#define PURPLE_PRIORITY_DEFAULT
Definition: plugin.h:65