// XScreenSaverAway Gaim Plugin // // Description // ----------- // Activates personal away message when xscreensaver is activated. // // Change Log // ---------- // version 0.67 (03/18/2004): // * Changed 'WEBSITE' to 'GAIM_WEBSITE' to comply with the latest API // - Benjamin Ritcey // // version 0.66 (07/19/2003): // * Updated to latest API - Devin Bayer // // version 0.65 (07/18/2003): // * Updated to latest API - Devin Bayer // // version 0.64 (06/18/2003): // * upgraded to gaim 0.63/0.64 Plugin API - Dario Sarango // // version 0.0 (??/??/2002): // * Initial Version, Cyril Bellot // // Copying // ------- // Copyright (C) 2003, Devin Bayer // // Credit to: // autoaway.c plugin // notify.c plugin // xscreensaver program // Cyril Bellot // Dario Sarango // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // Compiling and Installing the plugin // ----------------------------------- // 1.) Copy this xscreensaveraway.c file to the /plugins directory. // 2.) Type make xscreensaveraway.so // 3.) Copy xscreensaveraway.so to ${HOME}/.gaim/ // 4.) Go to Prefs->Plugins and Load XScreenSaverAway. // // Configuring the plugin // ---------------------- // To configure the plugin, goto Prefs->Plugins->XScreenSaverAway. Then read the next // section. // // Using the plugin // ---------------- // When xscreensaver actives, you will be away. // These includes must be at the top of each plugin, in this order. #include "internal.h" #include "config.h" #include "debug.h" #include "gaim.h" // Other includes for this plugin: #include "gtkplugin.h" #include "gtkutils.h" #include "gtkprefs.h" #include "ui.h" #include "prefs.h" #include "notify.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include // Globals static gint goon; static gint xlocked=0; static guint aa_timeout; /* Default interval check */ static guint aa_delay=2; // Imports from GAIM G_MODULE_IMPORT void default_away_menu_init(GtkWidget *); // Prototypes static void save_plugin_prefs(); static gint xscreensaver_hndl() { if(xlocked==1) { if (!awaymessage) { struct away_message *default_away = NULL; const char *default_name; GSList *l; default_name = gaim_prefs_get_string("/core/away/default_message"); for(l = away_messages; l; l = l->next) { if(!strcmp(default_name, ((struct away_message *)l->data)->name)) { default_away = l->data; break; } } if(!default_away && away_messages) default_away = away_messages->data; gaim_debug(GAIM_DEBUG_INFO, "xssaway", "XScreenSaver is active. Going away: %s\n",default_away->name); do_away_message(NULL,default_away); } } // FIXME: I don't like this, but it should be a pref. //if(xlocked==2) { // if (awaymessage) // do_im_back(NULL,NULL); // xlocked=0; //} if(aa_timeout>0) gtk_timeout_remove(aa_timeout); aa_timeout=gtk_timeout_add(1000*aa_delay, (GtkFunction)xscreensaver_hndl, NULL); return 1; } static void *xscreensaver_look(void *arg) { Display *dpy; Atom XA_SCREENSAVER_STATUS,XA_BLANK, XA_LOCK; char *v = 0; Window window; XWindowAttributes xgwa; XEvent event; CARD32 *last = 0; dpy=XOpenDisplay(getenv("DISPLAY")); window = RootWindow (dpy, 0); if (v) free (v); XGetWindowAttributes (dpy, window, &xgwa); XSelectInput (dpy, window, xgwa.your_event_mask | PropertyChangeMask); XA_SCREENSAVER_STATUS = XInternAtom (dpy, "_SCREENSAVER_STATUS", False); XA_LOCK = XInternAtom (dpy, "LOCK", False); XA_BLANK = XInternAtom (dpy, "BLANK", False); while (goon) { XNextEvent (dpy, &event); if (event.xany.type == PropertyNotify && event.xproperty.state == PropertyNewValue && event.xproperty.atom == XA_SCREENSAVER_STATUS) { Atom type; int format; unsigned long nitems, bytesafter; CARD32 *data = 0; if (XGetWindowProperty (dpy, RootWindow (dpy, 0), /* always screen #0 */ XA_SCREENSAVER_STATUS, 0, 999, False, XA_INTEGER, &type, &format, &nitems, &bytesafter, (unsigned char **) &data) == Success && type && data) { time_t tt; Bool changed = False; Bool running = False; if (type != XA_INTEGER || nitems < 3) { STATUS_LOSE: if (last) free (last); if (data) free (data); fprintf (stderr, "XSCREENSAVERAWAY-PLUGIN: bad status format on root window.\n");// return -1; } tt = (time_t) data[1]; if (tt <= (time_t) 666000000L) goto STATUS_LOSE; if (!last || data[0] != last[0]) { /* State changed. */ if ((data[0] == XA_BLANK) || (data[0] == XA_LOCK)) { //printf ("XSCREENSAVERAWAY-PLUGIN: LOCK\n"); xlocked=1; } else if (data[0] == 0) { //printf ("XSCREENSAVERAWAY-PLUGIN: UNBLANK\n"); xlocked=2; } else { goto STATUS_LOSE; } } if (!last) changed = True; else { int i; for (i = 2; i < nitems; i++) { if (data[i] != last[i]) changed = True; if (data[i]) running = True; } } if (last) free (last); last = data; } else { if (last) free (last); if (data) free (data); fprintf (stderr, "XSCREENSAVERAWAY-PLUGIN: no saver status on root window.\n"); } } } return NULL; } static void set_delay_time(GtkWidget *spinner,GtkWidget *nop) { aa_delay = CLAMP(gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(spinner)),1,30); if(aa_timeout>0) gtk_timeout_remove(aa_timeout); aa_timeout=gtk_timeout_add(1000*aa_delay, (GtkFunction)xscreensaver_hndl, NULL); save_plugin_prefs(); } static void save_plugin_prefs() { gchar buf[1000]; FILE *fp; snprintf(buf, 1000, "%s/.gaim/xscreensaverawayrc", getenv("HOME")); if (!(fp = fopen(buf, "w"))) { gaim_notify_error(NULL, NULL, _("Unable to write to config file"), _("XScreenSaverAway plugin")); return; } fprintf(fp, "%d=DELAY\n", aa_delay); fclose(fp); } static void load_plugin_prefs() { gchar buf[1000]; gchar **parsed; FILE *fp; g_snprintf(buf, sizeof(buf), "%s/.gaim/xscreensaverawayrc", getenv("HOME")); if (!(fp = fopen(buf, "r"))) return; while (fgets(buf, 1000, fp) != NULL) { parsed = g_strsplit(g_strchomp(buf), "=", 2); if (parsed[0] && parsed[1]) { if (!strcmp(parsed[1], "DELAY")) { aa_delay = atoi(parsed[0]); fprintf(stderr,"XSCREENSAVERAWAY-PLUGIN: delay=%d\n",aa_delay); } } g_strfreev(parsed); } fclose(fp); return; } /* * EXPORTED FUNCTIONS */ static gboolean plugin_load(GaimPlugin *stuff) { pthread_t tid; load_plugin_prefs(); aa_timeout=gtk_timeout_add(1000*aa_delay, (GtkFunction)xscreensaver_hndl, NULL); goon=1; pthread_create(&tid, NULL, &xscreensaver_look, NULL); return TRUE; } static gboolean plugin_unload() { goon=0; if(aa_timeout>0) gtk_timeout_remove(aa_timeout); return TRUE; } static GtkWidget *get_config_frame(GaimPlugin *plugin) { GtkWidget *prefs_away_menu, *spinner; GtkAdjustment *adj; GtkWidget *ret, *vbox, *hbox, *label; GtkSizeGroup *sg; sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); ret = gtk_vbox_new(FALSE, 18); gtk_container_set_border_width (GTK_CONTAINER (ret), 12); vbox = gaim_gtk_make_frame(ret, _("XScreenSaverAway Configuration")); // ****** AWAY MESSAGE PREF // See default_away_menu_init() for the actual pref setting label = gtk_label_new_with_mnemonic(_("Away m_essage:")); gtk_size_group_add_widget(sg, label); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); hbox = gtk_hbox_new(FALSE, 0); gtk_container_add(GTK_CONTAINER(vbox), hbox); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); prefs_away_menu = gtk_option_menu_new(); gtk_label_set_mnemonic_widget(GTK_LABEL(label), prefs_away_menu); default_away_menu_init(prefs_away_menu); gtk_widget_show(prefs_away_menu); gtk_box_pack_start(GTK_BOX(hbox), prefs_away_menu, FALSE, FALSE, 0); // ****** END AWAY MESSAGE PREF // ****** DELAY TIME PREF label = gtk_label_new_with_mnemonic(_("_Delay time:")); gtk_size_group_add_widget(sg, label); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); hbox = gtk_hbox_new(FALSE, 0); gtk_container_add(GTK_CONTAINER(vbox), hbox); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); adj = (GtkAdjustment *)gtk_adjustment_new(aa_delay,1,30,1,0,0); spinner = gtk_spin_button_new(GTK_ADJUSTMENT(adj),0,0); gtk_label_set_mnemonic_widget(GTK_LABEL(label), spinner); g_signal_connect(GTK_OBJECT(spinner), "value-changed", G_CALLBACK(set_delay_time), NULL); gtk_box_pack_start(GTK_BOX(hbox), spinner, FALSE, FALSE, 0); // ****** END DELAY TIME PREF gtk_widget_show_all(ret); return ret; } static GaimGtkPluginUiInfo ui_info = { get_config_frame }; static GaimPluginInfo info = { 2, /**< api_version */ GAIM_PLUGIN_STANDARD, /**< type */ GAIM_GTK_PLUGIN_TYPE, /**< ui_requirement */ 0, /**< flags */ NULL, /**< dependencies */ GAIM_PRIORITY_DEFAULT, /**< priority */ "xscreensaveraway", /**< id */ N_("XScreenSaverAway"), /**< name */ "0.67", /**< version */ /** summary */ N_("Sets away message when xscreensaver is activated."), /** description */ N_("Sets away message when xscreensaver is activated."), "Devin Bayer ", /**< author */ GAIM_WEBSITE, /**< homepage */ plugin_load, /**< load */ plugin_unload, /**< unload */ NULL, /**< destroy */ &ui_info, /**< ui_info */ NULL /**< extra_info */ }; static void init_plugin(GaimPlugin *plugin) { } GAIM_INIT_PLUGIN(xscreensaveraway, init_plugin, info);