-
-
Save Munawwar/76856c3fd3a334a77d3d to your computer and use it in GitHub Desktop.
Pidgin popup_notify
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Popup Mail Notification for Pidgin | |
* | |
* First taken from: | |
* Hello World Plugin | |
* Authors: | |
* Gary Kramlich, 2004 <grim@guifications.org>, | |
* John Bailey, 2007 <rekkanoryo@cpw.pidgin.im> | |
* GNU GPL2 | |
*/ | |
#ifdef HAVE_CONFIG_H | |
# include <config.h> | |
#endif | |
/* config.h may define PURPLE_PLUGINS; protect the definition here so that we | |
* don't get complaints about redefinition when it's not necessary. */ | |
#ifndef PURPLE_PLUGINS | |
# define PURPLE_PLUGINS | |
#endif | |
#include <glib.h> | |
/* This will prevent compiler errors in some instances and is better explained in the | |
* how-to documents on the wiki */ | |
#ifndef G_GNUC_NULL_TERMINATED | |
# if __GNUC__ >= 4 | |
# define G_GNUC_NULL_TERMINATED __attribute__((__sentinel__)) | |
# else | |
# define G_GNUC_NULL_TERMINATED | |
# endif | |
#endif | |
#include <string.h> | |
#include "debug.h" | |
#include "notify.h" | |
#include "gtkplugin.h" | |
#include "version.h" | |
#define PLUGIN_ID "gtk-mwr-popup_notify" | |
/* we're adding this here and assigning it in pn_plugin_load because we need | |
* a valid plugin handle for our call to purple_notify_message() in the | |
* plugin_action_test_cb() callback function */ | |
//All global functions and variables will have pn_ (meaning "popup notify") prefix | |
PurplePlugin *pn_Plugin = NULL; | |
GtkWindow *pn_window=NULL; | |
GtkLabel *pn_label=NULL; | |
GtkButton *pn_rightArrowBtn=NULL; | |
struct pn_Mail { | |
char *subject; | |
char *from; | |
char *to; | |
char *url; | |
}; | |
struct pn_MailList { | |
int index; | |
int count; | |
int recvCount; | |
GSList* list; | |
} pn_mailList; //Initialization done in pn_plugin_load | |
/*Prototypes*/ | |
/*Event handlers*/ | |
void rightArrowBtn_press_callback(GtkButton *button, gpointer user_data); | |
/*Constructors and destructors*/ | |
static void pn_mailInfo_allocate(char **subjects, char **froms, char **tos, char **urls, guint count) { | |
if(pn_mailList.count>0 || subjects==NULL || froms==NULL || tos==NULL || urls==NULL) { | |
return; | |
} | |
pn_mailList.recvCount=count; | |
int i; | |
purple_debug_info(PLUGIN_ID, "Allocating space for %d mails...\n",count); | |
for(i=0; i<count; i++) { | |
if(!(subjects[i]==NULL || froms[i]==NULL || tos[i]==NULL || urls[i]==NULL)) { | |
struct pn_Mail *mail=(struct pn_Mail*)malloc(sizeof (struct pn_Mail)); | |
purple_debug_info(PLUGIN_ID, "Allocating mail->subject for i=%d. ", i); | |
mail->subject=g_strdup(subjects[i]); | |
purple_debug_info(PLUGIN_ID, "Memory=%d\n", (int)mail->subject); | |
purple_debug_info(PLUGIN_ID, "Allocating mail->from for i=%d. ", i); | |
mail->from=g_strdup(froms[i]); | |
purple_debug_info(PLUGIN_ID, "Memory=%d\n", (int)mail->from); | |
purple_debug_info(PLUGIN_ID, "Allocating mail->to for i=%d. ", i); | |
mail->to=g_strdup(tos[i]); | |
purple_debug_info(PLUGIN_ID, "Memory=%d\n", (int)mail->to); | |
purple_debug_info(PLUGIN_ID, "Allocating mail->url for i=%d. ", i); | |
mail->url=g_strdup(urls[i]); | |
purple_debug_info(PLUGIN_ID, "Memory=%d\n", (int)mail->url); | |
pn_mailList.list = g_slist_append(pn_mailList.list, mail); | |
pn_mailList.count++; | |
} | |
if(subjects[i]==NULL && froms[i]==NULL && tos[i]==NULL && urls[i]==NULL) { | |
break; | |
} | |
} | |
purple_debug_info(PLUGIN_ID, "Allocation Done.\n"); | |
} | |
static void pn_mailInfo_deallocate() { | |
if(pn_mailList.count>0) { | |
int i; | |
purple_debug_info(PLUGIN_ID, "Deallocating...\n"); | |
for(i=0; i<pn_mailList.count; i++) { | |
struct pn_Mail *mail=(struct pn_Mail*)(g_slist_nth(pn_mailList.list,i)->data); | |
purple_debug_info(PLUGIN_ID, "Dellocating. mail->subject for i=%d. ", i); | |
purple_debug_info(PLUGIN_ID, "Memory=%d\n", (int)mail->subject); | |
g_free(mail->subject); | |
purple_debug_info(PLUGIN_ID, "Dellocating. mail->from for i=%d. ", i); | |
purple_debug_info(PLUGIN_ID, "Memory=%d\n",(int)mail->from); | |
g_free(mail->from); | |
purple_debug_info(PLUGIN_ID, "Dellocating. mail->to for i=%d. ", i); | |
purple_debug_info(PLUGIN_ID, "Memory=%d\n",(int)mail->to); | |
g_free(mail->to); | |
purple_debug_info(PLUGIN_ID, "Dellocating. mail->url for i=%d. ", i); | |
purple_debug_info(PLUGIN_ID, "Memory=%d\n",(int)mail->url); | |
g_free(mail->url); | |
} | |
pn_mailList.recvCount=0; | |
pn_mailList.count=0; | |
pn_mailList.index=-1; | |
g_slist_free(pn_mailList.list); | |
pn_mailList.list=NULL; | |
purple_debug_info(PLUGIN_ID, "Deallocation Done.\n"); | |
} | |
} | |
static void pn_destroyWindow() { | |
if(pn_window!=NULL) { | |
gtk_widget_destroy((GtkWidget*)pn_window); | |
pn_window=NULL; | |
pn_label=NULL; | |
pn_rightArrowBtn=NULL; | |
pn_mailInfo_deallocate(); | |
} | |
} | |
static void pn_createWindow() { | |
pn_window = (GtkWindow*) gtk_window_new (GTK_WINDOW_TOPLEVEL); | |
gtk_window_set_title(pn_window,"New Mail"); | |
//Set the border width of the pn_window. | |
gtk_container_set_border_width (GTK_CONTAINER(pn_window), 0); | |
gtk_window_set_type_hint (pn_window,GDK_WINDOW_TYPE_HINT_UTILITY); | |
gtk_window_set_gravity (pn_window,GDK_GRAVITY_SOUTH_EAST); | |
gtk_window_set_keep_above (pn_window, TRUE); | |
//Container elements | |
GtkBox *vbox = (GtkBox*) gtk_vbox_new(FALSE, 3); //TRUE = Allot equal spacing, 3px spacing between children | |
GtkBox *hbox = (GtkBox*) gtk_hbox_new(FALSE, 3); | |
//Create pn_label | |
pn_label = (GtkLabel*) gtk_label_new (""); | |
//Create Arrow | |
pn_rightArrowBtn = (GtkButton*) gtk_button_new(); | |
GtkWidget* rightArrow = gtk_arrow_new(GTK_ARROW_RIGHT,GTK_SHADOW_OUT); | |
gtk_container_add(GTK_CONTAINER(pn_rightArrowBtn), rightArrow); | |
gtk_box_pack_start(hbox, (GtkWidget*)pn_rightArrowBtn, FALSE, FALSE, 0); | |
gtk_container_add(GTK_CONTAINER(vbox), (GtkWidget*)pn_label); | |
gtk_box_pack_end(vbox, (GtkWidget*)hbox, FALSE, FALSE, 0); | |
gtk_container_add(GTK_CONTAINER(pn_window), (GtkWidget*)vbox); | |
gtk_widget_set_size_request(rightArrow,30,30); | |
gtk_widget_set_size_request((GtkWidget*)pn_rightArrowBtn,30,30); | |
//Set button signal | |
g_signal_connect (pn_rightArrowBtn, "clicked", G_CALLBACK (rightArrowBtn_press_callback), NULL); | |
} | |
/*Helper functions*/ | |
static void showWindow() { | |
gtk_widget_show_all((GtkWidget*)pn_window); | |
gtk_window_present(pn_window); | |
int window_width, window_height, offset=50; | |
gtk_window_get_size(pn_window, &window_width, &window_height); | |
gtk_window_move(pn_window, gdk_screen_width() - window_width, gdk_screen_height() - window_height - offset); | |
} | |
static void showMail(int index) { | |
if(index<0 || index>=pn_mailList.count) { | |
return; | |
} | |
struct pn_Mail *mail=(struct pn_Mail*)(g_slist_nth(pn_mailList.list,index)->data); | |
pn_mailList.index=index; | |
char msg[1000]=""; | |
sprintf(msg, "New Mail %d/%d", index+1, pn_mailList.recvCount); | |
gtk_window_set_title(pn_window,msg); | |
sprintf(msg, "Acc: %s\nFrom %s\nSubject: %s", mail->to, mail->from, mail->subject); | |
gtk_label_set_text (pn_label,msg); | |
showWindow(); | |
} | |
/*Even handlers*/ | |
void rightArrowBtn_press_callback(GtkButton *button, gpointer user_data) { | |
if(pn_mailList.count>0) { | |
purple_debug_info(PLUGIN_ID, "rightArrowBtn_press_callback index=%d\n", (pn_mailList.index+1)%pn_mailList.count); | |
purple_debug_info(PLUGIN_ID, "rightArrowBtn_press_callback count=%d\n", pn_mailList.count); | |
showMail((pn_mailList.index+1)%pn_mailList.count); | |
} | |
} | |
/************************************************************************** | |
* Notify signals callbacks | |
**************************************************************************/ | |
static void pn_notify_email_cb(char *subject, char *from, char *to, char *url) { | |
pn_destroyWindow(); //Destroy if exists | |
pn_createWindow(); | |
char *subjects[1],*froms[1],*tos[1],*urls[1]; | |
subjects[0]=subject; | |
froms[0]=from; | |
tos[0]=to; | |
urls[0]=url; | |
pn_mailInfo_allocate(subjects,froms,tos,urls,1); | |
showMail(0); | |
// char msg[1000]=""; | |
// sprintf(msg, "Acc: %s\nFrom %s\nSubject: %s", to, from, subject); | |
// purple_notify_info(PLUGIN_ID,"New Mail",msg,""); | |
} | |
static void pn_notify_emails_cb(char **subjects, char **froms, char **tos, char **urls, guint count) { | |
pn_destroyWindow(); //Destroy if exists | |
pn_createWindow(); | |
pn_mailInfo_allocate(subjects,froms,tos,urls,count); | |
showMail(0); | |
} | |
static gboolean pn_plugin_load(PurplePlugin * plugin) { | |
pn_Plugin = plugin; /* assign this here so we have a valid handle later */ | |
/*Initialize global objects*/ | |
pn_mailList.list=NULL; | |
pn_mailList.index=-1; | |
pn_mailList.count=0; | |
pn_mailList.recvCount=0; | |
//Some debug info | |
//purple_debug_info(PLUGIN_ID, "INFO level debug message. i = %d, f = %f, s = %s\n", i, f, s); | |
purple_debug_info(PLUGIN_ID,"Plugin loaded"); | |
/* Notify signals */ | |
void *notify_handle = purple_notify_get_handle(); | |
purple_signal_connect(notify_handle, "displaying-email-notification", pn_Plugin, PURPLE_CALLBACK(pn_notify_email_cb), NULL); | |
purple_signal_connect(notify_handle, "displaying-emails-notification", pn_Plugin, PURPLE_CALLBACK(pn_notify_emails_cb), NULL); | |
return TRUE; | |
} | |
static gboolean pn_plugin_unload(PurplePlugin * plugin) { | |
pn_destroyWindow(); | |
return TRUE; | |
} | |
static void pn_plugin_destroy(PurplePlugin *plugin) { | |
if(pn_window!=NULL) { | |
gtk_widget_destroy((GtkWidget*)pn_window); | |
/* Hope the OS will free memory :P*/ | |
} | |
} | |
/* For specific notes on the meanings of each of these members, consult the C Plugin Howto | |
* on the website. */ | |
static PurplePluginInfo info = { | |
PURPLE_PLUGIN_MAGIC,/* Plugin magic, this must always be | |
PURPLE_PLUGIN_MAGIC. | |
*/ | |
PURPLE_MAJOR_VERSION,/* This is also defined in libpurple. It helps | |
libpurple's plugin system determine which | |
version of libpurple this plugin was | |
compiled for, and whether loading it will | |
cause problems. | |
*/ | |
PURPLE_MINOR_VERSION, /* See previous */ | |
PURPLE_PLUGIN_STANDARD, | |
PIDGIN_PLUGIN_TYPE, /* This field is the UI requirement. If you're | |
writing a core plugin, this must be NULL | |
and the plugin must not contain any UI | |
code. If you're writing a Pidgin plugin, | |
you need to use PIDGIN_PLUGIN_TYPE. If you | |
are writing a Finch plugin, you would use | |
FINCH_PLUGIN_TYPE. | |
*/ | |
0, /* This field is for plugin flags. Currently, | |
the only flag available to plugins is | |
invisible (PURPLE_PLUGIN_FLAG_INVISIBLE). | |
It causes the plugin to NOT appear in the | |
list of plugins. | |
*/ | |
NULL, /* This is a GList of plugin dependencies. In | |
other words, a GList of plugin id's that | |
your plugin depends on. Set this value to | |
NULL no matter what. If your plugin has | |
dependencies, set them at run-time in the | |
plugin_init function. | |
*/ | |
PURPLE_PRIORITY_DEFAULT,/* This is the priority libpurple with give your | |
plugin. There are three possible values | |
for this field, PURPLE_PRIORITY_DEFAULT, | |
PURPLE_PRIORITY_HIGHEST, and | |
PURPLE_PRIORITY_LOWEST | |
*/ | |
PLUGIN_ID, /* This is your plugin's id */ | |
"Popup Notify", /* This is your plugin's name. This is what | |
will be displayed for your plugin in the UI. | |
*/ | |
"1.0", /* This is the plugin version */ | |
"Popup mail notification", /* This is the short summary of your plugin. */ | |
"Popup mail notification", /* This is the description of your plugin. It | |
can be as long and as descriptive as you | |
like. | |
*/ | |
"Munawwar Firoz <contact.munawwar@gmail.com>", /* Me name and email */ | |
"http://munawwar.leadhoster.com", /* Website. Eh, At least the site exists :P */ | |
pn_plugin_load, /* This is a pointer to a function for | |
libpurple to call when it is loading the | |
plugin. It should be of the type: | |
gboolean plugin_load(PurplePlugin *plugin) | |
Returning FALSE will stop the loading of the | |
plugin. Anything else would evaluate as | |
TRUE and the plugin will continue to load. | |
*/ | |
pn_plugin_unload, /* Same as above except it is called when | |
libpurple tries to unload your plugin. It | |
should be of the type: | |
gboolean plugin_unload(PurplePlugin *plugin) | |
Returning TRUE will tell libpurple to | |
continue unloading while FALSE will stop | |
the unloading of your plugin. | |
*/ | |
pn_plugin_destroy, /* Similar to the two above members, except | |
this is called when libpurple tries to | |
destory the plugin. This is generally only | |
called when for some reason or another the | |
plugin fails to probe correctly. It should | |
be of the type: | |
void plugin_destroy(PurplePlugin *plugin) | |
*/ | |
NULL, /* This is a pointer to a UI-specific struct. | |
For a Pidgin plugin it will be a pointer to a | |
PidginPluginUiInfo struct, for example. | |
*/ | |
NULL, /* This is a pointer to either a | |
PurplePluginLoaderInfo struct or a | |
PurplePluginProtocolInfo struct, and is | |
beyond the scope of this document. | |
*/ | |
NULL, /* This is a pointer to a PurplePluginUiInfo | |
struct. It is a core/ui split way for | |
core plugins to have a UI configuration | |
frame. You can find an example of this | |
code in: | |
libpurple/plugins/pluginpref_example.c | |
*/ | |
NULL, /* This is a function pointer where you can define | |
"plugin actions". The UI controls how | |
they're displayed. It should be of the | |
type: | |
GList *function_name(PurplePlugin *plugin, | |
gpointer context) | |
It must return a GList of | |
PurplePluginActions. | |
*/ | |
NULL, /* This is a pointer reserved for future use. | |
We set it to NULL to indicate we don't | |
need it. | |
*/ | |
NULL, /* This is a pointer reserved for future use. | |
We set it to NULL to indicate we don't | |
need it. | |
*/ | |
NULL, /* This is a pointer reserved for future use. | |
We set it to NULL to indicate we don't | |
need it. | |
*/ | |
NULL /* This is a pointer reserved for future use. | |
We set it to NULL to indicate we don't | |
need it. | |
*/ | |
}; | |
static void pn_init_plugin() { | |
} | |
PURPLE_INIT_PLUGIN (hello_world, pn_init_plugin, info) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment