/*
* perl.c - helper functions for Perl interface
*
* $Id: perl.c,v 1.28 2000/07/19 06:26:21 sc Exp $
*/
/* Copyright (C) 1999-2000 Sergey Chernikov (sc@ivvs.ul.ru)
*
* Authors: Sergey Chernikov <sc@ivvs.ul.ru>
*
* 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
*/
#include "grn_consts.h"
#undef PACKAGE
#ifdef USE_PERL
#include <EXTERN.h>
#include <perl.h>
#include <XSUB.h>
#if 0
#include <stdio.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#endif
#undef PACKAGE
#undef _
#include "grn_types.h"
#include "grn_util.h"
#include "grn_perl.h"
#include "grn_msgview.h"
#include "grn_config.h"
#include "grn_misc.h"
extern grn_session *GRN;
extern void xs_init(void);
static PerlInterpreter *my_perl = NULL;
GSList *perl_hooks;
GSList *perl_commands;
GSList *perl_files = NULL;
XS(XS_GRN_add_hook);
XS(XS_GRN_add_command);
XS(XS_GRN_html_escape);
XS(XS_GRN_subst_vars);
XS(XS_GRN_get_config);
XS(XS_GRN_get_font_pal);
XS(XS_GRN_get_color_pal);
XS(XS_GRN_mew_text_insert);
XS(XS_GRN_mew_text_select);
XS(XS_GRN_mew_text_get_selection);
XS(XS_GRN_mew_text_get);
XS(XS_GRN_mew_text_delete);
XS(XS_GRN_entry_text_get);
XS(XS_GRN_entry_text_set);
XS(XS_GRN_entry_text_delete);
XS(XS_GRN_error_dialog);
static gchar *escape_quotes(gchar *src)
{
gchar *tmp_buf;
gchar *i, *j;
tmp_buf = g_malloc(strlen(src)*2 + 1);
for (i=src, j=tmp_buf; *i; i++, j++)
{
if (*i == '\'' || *i == '\\') *j++ = '\\';
*j = *i;
}
*j = '\0';
return tmp_buf;
}
static glong execute_perl(gchar *function, gchar *args)
{
gchar *perl_cmd = NULL, *eargs;
SV *ret;
eargs = escape_quotes(args);
perl_cmd = g_strdup_printf("&%s('%s')", function, eargs);
str_free(&eargs);
ret = perl_eval_pv(perl_cmd, TRUE);
str_free(&perl_cmd);
return SvIV(ret);
}
int perl_load_file(gchar *script_name)
{
glong retval;
retval = execute_perl("load_file", script_name);
perl_files = g_slist_append(perl_files, g_strdup(script_name));
return retval;
}
void perl_autoload_file(gchar *script_name)
{
perl_load_file(script_name);
}
void perl_init(gboolean autoload)
{
gchar *perl_args[] = {"", "-e", "0"};
gchar pl_load_file[]= "sub load_file()\n"
"{ (my $file_name) = @_;\n"
"open(FH,$file_name) or return 2;\n"
"local($/)=undef; $file=<FH>;\n"
"close(FH); eval($file);\n"
"eval($file) if $@;\n"
"return 1 if $@; return 0; }";
my_perl = perl_alloc();
if (! my_perl)
{
g_warning(_("Not enough memory!"));
return;
}
perl_construct(my_perl);
if (perl_parse(my_perl, xs_init, 3, perl_args, NULL))
{
g_warning(_("Error loading Perl"));
return;
}
perl_eval_pv(pl_load_file, TRUE);
perl_hooks = NULL; perl_commands = NULL;
newXS("GRN::add_hook", XS_GRN_add_hook, "GRN");
newXS("GRN::add_command", XS_GRN_add_command, "GRN");
newXS("GRN::html_escape", XS_GRN_html_escape, "GRN");
newXS("GRN::subst_vars", XS_GRN_subst_vars, "GRN");
newXS("GRN::get_config", XS_GRN_get_config, "GRN");
newXS("GRN::get_font_pal", XS_GRN_get_font_pal, "GRN");
newXS("GRN::get_color_pal", XS_GRN_get_color_pal, "GRN");
newXS("GRN::mew_text_insert", XS_GRN_mew_text_insert, "GRN");
newXS("GRN::mew_text_select", XS_GRN_mew_text_select, "GRN");
newXS("GRN::mew_text_get_selection", XS_GRN_mew_text_get_selection, "GRN");
newXS("GRN::mew_text_get", XS_GRN_mew_text_get, "GRN");
newXS("GRN::mew_text_delete", XS_GRN_mew_text_delete, "GRN");
newXS("GRN::entry_text_get", XS_GRN_entry_text_get, "GRN");
newXS("GRN::entry_text_delete", XS_GRN_entry_text_delete, "GRN");
newXS("GRN::entry_text_set", XS_GRN_entry_text_set, "GRN");
newXS("GRN::error_dialog", XS_GRN_error_dialog, "GRN");
if (autoload)
{
gchar *s = gnome_util_prepend_user_home(".grn/hooks/Perl");
files_foreach(s, perl_autoload_file);
str_free(&s);
s = gnome_util_prepend_user_home(".grn/commands/Perl");
files_foreach(s, perl_autoload_file);
str_free(&s);
}
}
void perl_end(void)
{
while (perl_commands)
{
perl_command_handler *pch = perl_commands->data;
perl_commands = g_slist_remove(perl_commands, pch);
str_free(&(pch->command_name)); str_free(&(pch->handler_name));
g_free(pch);
}
while (perl_hooks)
{
perl_hook_handler *phh = perl_hooks->data;
perl_hooks = g_slist_remove(perl_hooks, phh);
str_free(&(phh->hook_name)); str_free(&(phh->handler_name));
g_free(phh);
}
while (perl_files)
{
gchar *s = perl_files->data;
perl_files = g_slist_remove(perl_files, s);
str_free(&s);
}
perl_destruct(my_perl);
perl_free(my_perl); my_perl = NULL;
}
void grn_perl_restart(void)
{
GSList *l, *sl_pf = NULL;
for (l=perl_files; l; l=l->next) sl_pf = g_slist_append(sl_pf, g_strdup(l->data));
if (my_perl) perl_end();
perl_init(FALSE);
while (sl_pf)
{
gchar *s = sl_pf->data;
perl_load_file(s);
sl_pf = g_slist_remove(sl_pf, s);
str_free(&s);
}
g_slist_free(sl_pf);
}
GSList *grn_perl_list(void)
{
GSList *ret=NULL, *l;
gchar **row;
for (l=perl_commands; l; l=l->next)
{
perl_command_handler *pch = l->data;
row = g_malloc(sizeof(gpointer));
row[0] = g_strdup(_("command"));
row[1] = g_strdup(pch->command_name);
row[2] = g_strdup(pch->handler_name);
ret = g_slist_prepend(ret, row);
}
for (l=perl_hooks; l; l=l->next)
{
perl_hook_handler *phh = l->data;
row = g_malloc(sizeof(gpointer));
row[0] = g_strdup(_("hook"));
row[1] = g_strdup(phh->hook_name);
row[2] = g_strdup(phh->handler_name);
ret = g_slist_prepend(ret, row);
}
for (l=perl_files; l; l=l->next)
{
row = g_malloc(sizeof(gpointer));
row[0] = g_strdup(_("file"));
row[1] = g_strdup(l->data);
row[2] = NULL;
ret = g_slist_prepend(ret, row);
}
ret = g_slist_reverse(ret);
return ret;
}
/*
0 none
1 t_msgheaders
2 t_message
3 grn_mime_part
*/
static gint get_data_type(gchar *hookname)
{
if (! strcmp(hookname, "GetScore")) return 1;
if (! strcmp(hookname, "PreShow")) return 2;
if (! strcmp(hookname, "TemplateNew")) return 2;
if (! strcmp(hookname, "TemplateMNew")) return 2;
if (! strcmp(hookname, "TemplateReply")) return 2;
if (! strcmp(hookname, "TemplateMReply")) return 2;
if (! strcmp(hookname, "TemplateForward")) return 2;
if (! strcmp(hookname, "TemplateMForward")) return 2;
if (! strcmp(hookname, "Quote")) return 2;
if (! strcmp(hookname, "PrePost")) return 2;
if (! strcmp(hookname, "PreSend")) return 2;
if (! strcmp(hookname, "PreShowHeader")) return 2;
if (! strcmp(hookname, "PreShowFooter")) return 2;
if (! strcmp(hookname, "PreShowPart")) return 3;
return 0;
}
static gint get_data1_type(gchar *hookname)
{
if (! strcmp(hookname, "GetScore")) return 0;
if (! strcmp(hookname, "PreShow")) return 0;
if (! strcmp(hookname, "TemplateNew")) return 0;
if (! strcmp(hookname, "TemplateMNew")) return 0;
if (! strcmp(hookname, "TemplateReply")) return 2;
if (! strcmp(hookname, "TemplateMReply")) return 2;
if (! strcmp(hookname, "TemplateForward")) return 2;
if (! strcmp(hookname, "TemplateMForward")) return 2;
if (! strcmp(hookname, "Quote")) return 2;
if (! strcmp(hookname, "PrePost")) return 0;
if (! strcmp(hookname, "PreSend")) return 0;
if (! strcmp(hookname, "PreShowHeader")) return 0;
if (! strcmp(hookname, "PreShowFooter")) return 0;
if (! strcmp(hookname, "PreShowPart")) return 0;
return 0;
}
/*
1 param in global scope
2 param as an argument
*/
static gint get_arg_type(gchar *hookname)
{
if (! strcmp(hookname, "GetScore")) return 1;
if (! strcmp(hookname, "PreShow")) return 1;
if (! strcmp(hookname, "TemplateNew")) return 1;
if (! strcmp(hookname, "TemplateMNew")) return 1;
if (! strcmp(hookname, "TemplateReply")) return 1;
if (! strcmp(hookname, "TemplateMReply")) return 1;
if (! strcmp(hookname, "TemplateForward")) return 1;
if (! strcmp(hookname, "TemplateMForward")) return 1;
if (! strcmp(hookname, "Quote")) return 1;
if (! strcmp(hookname, "PrePost")) return 1;
if (! strcmp(hookname, "PreSend")) return 1;
if (! strcmp(hookname, "PreShowHeader")) return 1;
if (! strcmp(hookname, "PreShowFooter")) return 1;
if (! strcmp(hookname, "PreShowPart")) return 1;
return 0;
}
/*
0 none
1 param in global scope
2 param as an argument
*/
static gint get_arg1_type(gchar *hookname)
{
if (! strcmp(hookname, "GetScore")) return 0;
if (! strcmp(hookname, "PreShow")) return 0;
if (! strcmp(hookname, "TemplateNew")) return 0;
if (! strcmp(hookname, "TemplateMNew")) return 0;
if (! strcmp(hookname, "TemplateReply")) return 1;
if (! strcmp(hookname, "TemplateMReply")) return 1;
if (! strcmp(hookname, "TemplateForward")) return 1;
if (! strcmp(hookname, "TemplateMForward")) return 1;
if (! strcmp(hookname, "Quote")) return 1;
if (! strcmp(hookname, "PrePost")) return 0;
if (! strcmp(hookname, "PreSend")) return 0;
if (! strcmp(hookname, "PreShowHeader")) return 0;
if (! strcmp(hookname, "PreShowFooter")) return 0;
if (! strcmp(hookname, "PreShowPart")) return 0;
return 0;
}
static gboolean read_only_data(gchar *hookname)
{
if (! strcmp(hookname, "GetScore")) return TRUE;
return FALSE;
}
/*static gboolean read_only_data1(gchar *hookname)
{
return TRUE;
}*/
static void put_str_to_hash(HV *hash, gchar *key, gchar *src)
{
if (! src) return;
hv_store(hash, key, strlen(key), newSVpv(src, 0), 0);
}
static void put_int_to_hash(HV *hash, gchar *key, glong src)
{
hv_store(hash, key, strlen(key), newSViv(src), 0);
}
static void rm_from_hash(HV *hash, gchar *key)
{
hv_delete(hash, key, strlen(key), G_DISCARD);
}
static gchar *get_str_from_hash(HV *hash, gchar *key)
{
SV **sv;
gchar *tmp;
guint len;
sv = hv_fetch(hash, key, strlen(key), 0);
if (! sv) return NULL;
SvPV(*sv, len);
if (len <= 0) return NULL;
tmp = (gchar *) g_malloc(len + 1);
strcpy(tmp, SvPV(*sv, len));
tmp[len] = '\0';
return tmp;
}
static glong get_int_from_hash(HV *hash, gchar *key)
{
SV **sv;
sv = hv_fetch(hash, key, strlen(key), 0);
if (sv) return SvIV(*sv);
return 0;
}
static void fill_extra_hdr(gchar *key, gchar *value, HV *mht)
{
if (! value) return;
put_str_to_hash(mht, key, value);
}
static void fill_mhdrs_hash(HV *mht, t_msgheaders *mh)
{
if (! mh) return;
put_int_to_hash(mht, "Number", mh->number);
put_int_to_hash(mht, "Lines", mh->lines);
put_int_to_hash(mht, "Size", mh->size);
put_int_to_hash(mht, "ParsedDate", mh->parsed_date);
put_str_to_hash(mht, "From", mh->from);
put_str_to_hash(mht, "Subject", mh->subject);
put_str_to_hash(mht, "Date", mh->date);
put_str_to_hash(mht, "Message-ID", mh->id);
put_str_to_hash(mht, "References", mh->ref);
put_str_to_hash(mht, "Xref", mh->xref);
put_str_to_hash(mht, "Path", mh->path);
if (mh->newsgroups) put_str_to_hash(mht, "Newsgroups", mh->newsgroups);
else if (mh->grp) put_str_to_hash(mht, "Newsgroups", mh->grp->name);
put_str_to_hash(mht, "To", mh->to);
if (mh->grp) put_str_to_hash(mht, "Group", mh->grp->name);
if (mh->extra_hdrs)
g_hash_table_foreach(mh->extra_hdrs, (GHFunc) fill_extra_hdr, mht);
}
static void fill_msg_hash(HV *mht, t_message *m)
{
if (! m) return;
fill_mhdrs_hash(mht, m->mh);
put_str_to_hash(mht, "body", m->body);
put_int_to_hash(mht, "nChildren", m->nchildren);
put_int_to_hash(mht, "tagged", m->tagged);
}
static void fill_mp_hash(HV *mph, grn_mime_part *mp)
{
if (! mp) return;
put_int_to_hash(mph, "size", mp->size);
put_str_to_hash(mph, "type", mp->type);
put_str_to_hash(mph, "subtype", mp->subtype);
put_str_to_hash(mph, "encoding", mp->enc);
put_str_to_hash(mph, "filename", mp->filename);
put_str_to_hash(mph, "data", mp->data);
}
static void fill_mhdrs_from_hash(t_msgheaders *mh, HV *mht)
{
HE *iter;
if (! mh) return;
mh->lines = get_int_from_hash(mht, "Lines");
rm_from_hash(mht, "Lines");
mh->size = get_int_from_hash(mht, "Size");
rm_from_hash(mht, "Size");
mh->parsed_date = get_int_from_hash(mht, "ParsedDate");
rm_from_hash(mht, "ParsedDate");
str_free(&(mh->from));
mh->from = get_str_from_hash(mht, "From");
rm_from_hash(mht, "From");
str_free(&(mh->subject));
mh->subject = get_str_from_hash(mht, "Subject");
rm_from_hash(mht, "Subject");
str_free(&(mh->date));
mh->date = get_str_from_hash(mht, "Date");
rm_from_hash(mht, "Date");
str_free(&(mh->id));
mh->id = get_str_from_hash(mht, "Message-ID");
rm_from_hash(mht, "Message-ID");
str_free(&(mh->ref));
mh->ref = get_str_from_hash(mht, "References");
rm_from_hash(mht, "References");
str_free(&(mh->newsgroups));
mh->newsgroups = get_str_from_hash(mht, "Newsgroups");
rm_from_hash(mht, "Newsgroups");
str_free(&(mh->to));
mh->to = get_str_from_hash(mht, "To");
rm_from_hash(mht, "To");
str_free(&(mh->path));
mh->path = get_str_from_hash(mht, "Path");
rm_from_hash(mht, "Path");
rm_from_hash(mht, "Xref");
rm_from_hash(mht, "Group");
rm_from_hash(mht, "Number");
t_msgheaders_rm_extra_hdrs(mh);
mh->extra_hdrs = g_hash_table_new(g_str_hash, g_str_equal);
hv_iterinit(mht);
while ((iter = hv_iternext(mht)))
{
I32 retlen;
gchar *key = g_strdup(hv_iterkey(iter, &retlen));
gchar *value;
if (str_check(key))
{
value = get_str_from_hash(mht, key);
g_hash_table_insert(mh->extra_hdrs, key, value);
}
}
}
static void fill_msg_from_hash(t_message *m, HV *mht)
{
if (! m) return;
str_free(&(m->body));
m->body = get_str_from_hash(mht, "body");
rm_from_hash(mht, "body");
m->pos = get_int_from_hash(mht, "pos");
rm_from_hash(mht, "pos");
m->tagged = get_int_from_hash(mht, "tagged");
rm_from_hash(mht, "tagged");
rm_from_hash(mht, "nChildren");
fill_mhdrs_from_hash(m->mh, mht);
}
static void fill_mp_from_hash(grn_mime_part *mp, HV *mph)
{
if (! mp) return;
mp->size = get_int_from_hash(mph, "size");
str_free(&(mp->type));
mp->type = get_str_from_hash(mph, "type");
str_free(&(mp->subtype));
mp->subtype = get_str_from_hash(mph, "subtype");
str_free(&(mp->enc));
mp->enc = get_str_from_hash(mph, "encoding");
str_free(&(mp->filename));
mp->filename = get_str_from_hash(mph, "filename");
str_free(&(mp->data));
mp->data = get_str_from_hash(mph, "data");
}
glong perl_hook_run(gchar *hookname, grn_session *sess, gpointer data, gpointer data1)
{
dSP;
HV *mht=NULL, *mht1=NULL;
GSList *handler;
perl_hook_handler *phh;
gint data_type, data1_type, arg_type, arg1_type;
glong ret = 0;
gchar *htname = NULL;
arg_type = get_arg_type(hookname);
data_type = get_data_type(hookname);
arg1_type = get_arg1_type(hookname);
data1_type = get_data1_type(hookname);
if (data_type == 3) htname = g_strdup("MPART");
else htname = g_strdup("MSG");
if (arg_type == 1) mht = perl_get_hv(htname, TRUE);
else mht = newHV();
str_free(&htname);
if (data_type == 3) htname = g_strdup("MPART1");
else htname = g_strdup("MSG1");
if (arg1_type == 1) mht1 = perl_get_hv(htname, TRUE);
else if (arg1_type == 2) mht1 = newHV();
str_free(&htname);
if ((data_type == 1) || (data_type == 2))
{
if (data_type == 1) fill_mhdrs_hash(mht, (t_msgheaders *) data);
else if (data_type == 2) fill_msg_hash(mht, (t_message *) data);
}
else if (data_type == 3) fill_mp_hash(mht, (grn_mime_part *) data);
if ((data1_type == 1) || (data1_type == 2))
{
if (data1_type == 1) fill_mhdrs_hash(mht1, (t_msgheaders *) data1);
else if (data1_type == 2) fill_msg_hash(mht1, (t_message *) data1);
}
else if (data1_type == 3) fill_mp_hash(mht, (grn_mime_part *) data1);
for (handler=perl_hooks; handler; handler=handler->next)
{
phh = (perl_hook_handler *) handler->data;
if (! strcmp(phh->hook_name, hookname))
{
if (arg_type >= 2)
{
ENTER;
SAVETMPS;
PUSHMARK(SP);
// XPUSHs(sv_2mortal(newSViv(123456789)));
// XPUSHs(sv_2mortal((SV *) mht));
PUTBACK;
}
if (arg_type <= 1) ret = execute_perl(phh->handler_name, "");
if (arg_type >= 2)
{
ret = perl_call_pv(phh->handler_name, G_SCALAR);
SPAGAIN;
if (ret == 1) ret = POPi;
else ret = 0;
PUTBACK;
FREETMPS;
LEAVE;
}
if (ret > 0)
{
if (! read_only_data(hookname))
{
if (data_type == 1) fill_mhdrs_from_hash((t_msgheaders *) data, mht);
else if (data_type == 2) fill_msg_from_hash((t_message *) data, mht);
else if (data_type == 3) fill_mp_from_hash((grn_mime_part *) data, mht);
}
hv_undef(mht); hv_undef(mht1);
return ret;
}
}
}
hv_undef(mht); hv_undef(mht1);
if (ret) return ret;
return (-1);
}
glong perl_command_run(gchar *cmd_name, grn_session *sess, gpointer data)
{
// dSP;
GSList *handler;
perl_command_handler *pch;
glong ret = 0;
for (handler=perl_commands; handler; handler=handler->next)
{
pch = (perl_command_handler *) handler->data;
if (! strcmp(pch->handler_name, cmd_name))
ret = execute_perl(pch->handler_name, "");
}
if (ret) return ret;
return (-1);
}
XS(XS_GRN_add_hook)
{
int junk;
perl_hook_handler *handler;
dXSARGS;
items = 0;
handler = g_malloc(sizeof(perl_hook_handler));
handler->hook_name = g_strdup(SvPV(ST(0), junk));
handler->handler_name = g_strdup(SvPV(ST(1), junk));
perl_hooks = g_slist_append(perl_hooks, handler);
XSRETURN_EMPTY;
}
XS(XS_GRN_add_command)
{
int junk;
perl_command_handler *handler;
dXSARGS;
items = 0;
handler = g_malloc(sizeof(perl_command_handler));
handler->context = SvIV(ST(0));
handler->command_name = g_strdup(SvPV(ST(1), junk));
handler->handler_name = g_strdup(SvPV(ST(2), junk));
perl_commands = g_slist_append(perl_commands, handler);
XSRETURN_EMPTY;
}
XS(XS_GRN_html_escape)
{
int junk;
gchar *s;
dXSARGS;
items = 0;
s = html_escape(SvPV(ST(0), junk));
XST_mPV(0, s);
str_free(&s);
XSRETURN(1);
}
XS(XS_GRN_subst_vars)
{
int junk;
gchar *s;
dXSARGS;
items = 0;
s = g_strdup(SvPV(ST(0), junk));
grn_subst_vars(&s);
XST_mPV(0, s);
str_free(&s);
XSRETURN(1);
}
XS(XS_GRN_get_config)
{
int junk;
gchar *s, *buf;
dXSARGS;
items = 0;
s = SvPV(ST(0), junk);
if ((! g_strcasecmp(s, "ver")) || (! g_strcasecmp(s, "version")))
XST_mPV(0, VERSION);
else if (! g_strcasecmp(s, "srv_autoconnect")) XST_mIV(0, grn_prefs.srv_autoconnect);
else if (! g_strcasecmp(s, "scripts_autoload")) XST_mIV(0, grn_prefs.scripts_autoload);
else if (! g_strcasecmp(s, "server")) XST_mPV(0, grn_prefs.nntp_server);
else if (! g_strcasecmp(s, "name")) XST_mPV(0, grn_prefs.name);
else if ((! g_strcasecmp(s, "email")) || (! g_strcasecmp(s, "e-mail")))
XST_mPV(0, grn_prefs.email);
else if ((! g_strcasecmp(s, "replyto")) || (! g_strcasecmp(s, "reply-to")))
XST_mPV(0, grn_prefs.replyto);
else if (! g_strcasecmp(s, "organization")) XST_mPV(0, grn_prefs.org);
else if (! g_strcasecmp(s, "re_quoting")) XST_mPV(0, grn_prefs.re_quoting);
else if (! g_strcasecmp(s, "font0")) XST_mPV(0, grn_prefs.fonts[0]);
else if (! g_strcasecmp(s, "font1")) XST_mPV(0, grn_prefs.fonts[1]);
else if (! g_strcasecmp(s, "font2")) XST_mPV(0, grn_prefs.fonts[2]);
else if (! g_strcasecmp(s, "font3")) XST_mPV(0, grn_prefs.fonts[3]);
else if (! g_strcasecmp(s, "font4")) XST_mPV(0, grn_prefs.fonts[4]);
else if (! g_strcasecmp(s, "fgcolor0"))
{
buf = c2s(grn_prefs.fg_colors[0]); XST_mPV(0, buf); str_free(&buf);
}
else if (! g_strcasecmp(s, "fgcolor1"))
{
buf = c2s(grn_prefs.fg_colors[1]); XST_mPV(0, buf); str_free(&buf);
}
else if (! g_strcasecmp(s, "fgcolor2"))
{
buf = c2s(grn_prefs.fg_colors[2]); XST_mPV(0, buf); str_free(&buf);
}
else if (! g_strcasecmp(s, "bgcolor0"))
{
buf = c2s(grn_prefs.bg_colors[0]); XST_mPV(0, buf); str_free(&buf);
}
else if (! g_strcasecmp(s, "bgcolor1"))
{
buf = c2s(grn_prefs.bg_colors[1]); XST_mPV(0, buf); str_free(&buf);
}
else if (! g_strcasecmp(s, "bgcolor2"))
{
buf = c2s(grn_prefs.bg_colors[2]); XST_mPV(0, buf); str_free(&buf);
}
else if (! g_strcasecmp(s, "cfm_group_read")) XST_mIV(0, grn_prefs.cfms[0]);
else if (! g_strcasecmp(s, "cfm_group_unread")) XST_mIV(0, grn_prefs.cfms[1]);
else if (! g_strcasecmp(s, "cfm_thread_read")) XST_mIV(0, grn_prefs.cfms[2]);
else if (! g_strcasecmp(s, "cfm_thread_unread")) XST_mIV(0, grn_prefs.cfms[3]);
else if (! g_strcasecmp(s, "cfm_abort_posting")) XST_mIV(0, grn_prefs.cfms[4]);
else if (! g_strcasecmp(s, "cfm_show_warnings")) XST_mIV(0, grn_prefs.cfms[5]);
else if (! g_strcasecmp(s, "cfm_show_messages")) XST_mIV(0, grn_prefs.cfms[6]);
else XST_mPV(0, "");
XSRETURN(1);
}
XS(XS_GRN_get_font_pal)
{
gint iarg, nmax;
dXSARGS;
items = 0;
iarg = SvIV(ST(0));
nmax = g_slist_length(grn_prefs.fontpal);
if (iarg > nmax) iarg = nmax;
if (iarg < 1) iarg = 1;
XST_mPV(0, g_slist_nth_data(grn_prefs.fontpal, iarg - 1));
XSRETURN(1);
}
XS(XS_GRN_get_color_pal)
{
gint iarg, nmax;
GdkColor *clr;
gchar *buf;
dXSARGS;
items = 0;
iarg = SvIV(ST(0));
nmax = g_slist_length(grn_prefs.colorpal);
if (iarg > nmax) iarg = nmax;
if (iarg < 1) iarg = 1;
clr = (GdkColor *) g_slist_nth_data(grn_prefs.colorpal, iarg - 1);
buf = c2s(*clr); XST_mPV(0, buf); str_free(&buf);
XSRETURN(1);
}
XS(XS_GRN_mew_text_insert)
{
int junk;
gchar *s;
GtkWidget *vbox, *text = NULL;
dXSARGS;
items = 0;
if (! GRN->focused) XSRETURN_EMPTY;
s = SvPV(ST(0), junk);
vbox = gtk_object_get_data(GTK_OBJECT(GRN->focused), KEY_MSGPOST);
if (vbox) text = gtk_object_get_data(GTK_OBJECT(vbox), KEY_TXT_BODY);
if ((! text) || (! GTK_IS_TEXT(text))) XSRETURN_EMPTY;
gtk_text_insert(GTK_TEXT(text), NULL, NULL, NULL, s, strlen(s));
XSRETURN_EMPTY;
}
XS(XS_GRN_mew_text_select)
{
gint start, end;
GtkWidget *vbox, *text = NULL;
dXSARGS;
items = 0;
if (! GRN->focused) XSRETURN_EMPTY;
start = SvIV(ST(0)); end = SvIV(ST(1));
vbox = gtk_object_get_data(GTK_OBJECT(GRN->focused), KEY_MSGPOST);
if (vbox) text = gtk_object_get_data(GTK_OBJECT(vbox), KEY_TXT_BODY);
if ((! text) || (! GTK_IS_TEXT(text))) XSRETURN_EMPTY;
gtk_editable_select_region(GTK_EDITABLE(text), start, end);
XSRETURN_EMPTY;
}
XS(XS_GRN_mew_text_get_selection)
{
GtkWidget *vbox, *text = NULL;
dXSARGS;
items = 0;
if (! GRN->focused) XSRETURN_EMPTY;
vbox = gtk_object_get_data(GTK_OBJECT(GRN->focused), KEY_MSGPOST);
if (vbox) text = gtk_object_get_data(GTK_OBJECT(vbox), KEY_TXT_BODY);
if ((! text) || (! GTK_IS_TEXT(text))) XSRETURN_EMPTY;
if (! GTK_EDITABLE(text)->has_selection) XSRETURN_EMPTY;
else {
XST_mIV(0, GTK_EDITABLE(text)->selection_start_pos);
XST_mIV(1, GTK_EDITABLE(text)->selection_end_pos);
XSRETURN(2);
}
}
XS(XS_GRN_mew_text_get)
{
gint start, end;
gchar *s;
GtkWidget *vbox, *text = NULL;
dXSARGS;
items = 0;
if (! GRN->focused) XSRETURN_EMPTY;
start = SvIV(ST(0)); end = SvIV(ST(1));
vbox = gtk_object_get_data(GTK_OBJECT(GRN->focused), KEY_MSGPOST);
if (vbox) text = gtk_object_get_data(GTK_OBJECT(vbox), KEY_TXT_BODY);
if ((! text) || (! GTK_IS_TEXT(text))) XSRETURN_EMPTY;
s = gtk_editable_get_chars(GTK_EDITABLE(text), start, end);
if (! s) XSRETURN_EMPTY;
else {
XST_mPV(0, s);
g_free(s);
XSRETURN(1);
}
}
XS(XS_GRN_mew_text_delete)
{
gint start, end;
GtkWidget *vbox, *text = NULL;
dXSARGS;
items = 0;
if (! GRN->focused) XSRETURN_EMPTY;
start = SvIV(ST(0)); end = SvIV(ST(1));
vbox = gtk_object_get_data(GTK_OBJECT(GRN->focused), KEY_MSGPOST);
if (vbox) text = gtk_object_get_data(GTK_OBJECT(vbox), KEY_TXT_BODY);
if ((! text) || (! GTK_IS_TEXT(text))) XSRETURN_EMPTY;
gtk_editable_delete_text(GTK_EDITABLE(text), start, end);
XSRETURN_EMPTY;
}
XS(XS_GRN_entry_text_get)
{
int junk;
gint start, end;
gchar *s, *s1;
GtkWidget *vbox, *entry = NULL;
dXSARGS;
items = 0;
if (! GRN->focused) XSRETURN_EMPTY;
s1 = SvPV(ST(0), junk);
start = SvIV(ST(1)); end = SvIV(ST(2));
vbox = gtk_object_get_data(GTK_OBJECT(GRN->focused), KEY_MSGPOST);
if (! vbox) vbox = gtk_object_get_data(GTK_OBJECT(GRN->focused), KEY_WND);
if (vbox) entry = gtk_object_get_data(GTK_OBJECT(vbox), s1);
if (! entry) XSRETURN_EMPTY;
if (! GTK_IS_EDITABLE(entry)) XSRETURN_EMPTY;
s = gtk_editable_get_chars(GTK_EDITABLE(entry), start, end);
if (! s) XSRETURN_EMPTY;
else {
XST_mPV(0, s);
g_free(s);
XSRETURN(1);
}
}
XS(XS_GRN_entry_text_delete)
{
int junk;
gchar *s1;
gint start, end;
GtkWidget *vbox, *entry = NULL;
dXSARGS;
items = 0;
if (! GRN->focused) XSRETURN_EMPTY;;
s1 = SvPV(ST(0), junk);
start = SvIV(ST(1)); end = SvIV(ST(2));
vbox = gtk_object_get_data(GTK_OBJECT(GRN->focused), KEY_MSGPOST);
if (! vbox) vbox = gtk_object_get_data(GTK_OBJECT(GRN->focused), KEY_WND);
if (vbox) entry = gtk_object_get_data(GTK_OBJECT(vbox), s1);
if (! entry) XSRETURN_EMPTY;
if (! GTK_IS_EDITABLE(entry)) XSRETURN_EMPTY;
gtk_editable_delete_text(GTK_EDITABLE(entry), start, end);
XSRETURN_EMPTY;
}
XS(XS_GRN_entry_text_set)
{
int junk;
gchar *s, *s1;
GtkWidget *vbox, *entry = NULL;
dXSARGS;
items = 0;
if (! GRN->focused) XSRETURN_EMPTY;;
s1 = SvPV(ST(0), junk);
s = SvPV(ST(1), junk);
vbox = gtk_object_get_data(GTK_OBJECT(GRN->focused), KEY_MSGPOST);
if (! vbox) vbox = gtk_object_get_data(GTK_OBJECT(GRN->focused), KEY_WND);
if (vbox) entry = gtk_object_get_data(GTK_OBJECT(vbox), s1);
if (! entry) XSRETURN_EMPTY;
if (! GTK_IS_EDITABLE(entry)) XSRETURN_EMPTY;
if (! GTK_EDITABLE(entry)->editable) XSRETURN_EMPTY;
gtk_entry_set_text(GTK_ENTRY(entry), s);
XSRETURN_EMPTY;
}
XS(XS_GRN_error_dialog)
{
int junk;
gchar *s1, *s2;
dXSARGS;
items = 0;
s1 = SvPV(ST(0), junk);
s2 = SvPV(ST(1), junk);
grn_error(s1, s2);
XSRETURN_EMPTY;
}
#endif
syntax highlighted by Code2HTML, v. 0.9.1