mirror of
https://github.com/irssi/irssi.git
synced 2024-12-04 14:46:39 -05:00
add perl code for textbuffer-formats
- compatibility shim for new line - make format accessible from perl - fix perl line IDs being mixed up due to wrapper
This commit is contained in:
parent
6b93d6e338
commit
57fb173130
@ -108,6 +108,7 @@ textui_sources = \
|
||||
textui/TextBufferView.xs \
|
||||
textui/Statusbar.xs \
|
||||
textui/Makefile.PL.in \
|
||||
textui/wrapper_buffer_line.h \
|
||||
textui/typemap \
|
||||
textui/module.h
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
#define PERL_NO_GET_CONTEXT
|
||||
#include "module.h"
|
||||
#include "wrapper_buffer_line.h"
|
||||
#include <irssi/src/fe-text/textbuffer-formats.h>
|
||||
|
||||
MODULE = Irssi::TextUI::TextBuffer PACKAGE = Irssi
|
||||
PROTOTYPES: ENABLE
|
||||
@ -12,7 +14,7 @@ Irssi::TextUI::Line
|
||||
textbuffer_line_prev(line)
|
||||
Irssi::TextUI::Line line
|
||||
CODE:
|
||||
RETVAL = line->prev;
|
||||
RETVAL = perl_wrap_buffer_line(line->buffer, line->line->prev);
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
@ -20,13 +22,12 @@ Irssi::TextUI::Line
|
||||
textbuffer_line_next(line)
|
||||
Irssi::TextUI::Line line
|
||||
CODE:
|
||||
RETVAL = line->next;
|
||||
RETVAL = perl_wrap_buffer_line(line->buffer, line->line->next);
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
void
|
||||
textbuffer_line_get_text(buffer, line, coloring)
|
||||
Irssi::TextUI::TextBuffer buffer
|
||||
textbuffer_line_get_text(line, coloring)
|
||||
Irssi::TextUI::Line line
|
||||
int coloring
|
||||
PREINIT:
|
||||
@ -34,8 +35,36 @@ PREINIT:
|
||||
SV *result;
|
||||
PPCODE:
|
||||
str = g_string_new(NULL);
|
||||
textbuffer_line2text(buffer, line, coloring, str);
|
||||
textbuffer_line2text(line->buffer, line->line, coloring, str);
|
||||
result = new_pv(str->str);
|
||||
XPUSHs(sv_2mortal(result));
|
||||
g_string_free(str, TRUE);
|
||||
|
||||
void
|
||||
textbuffer_line_get_format(line)
|
||||
Irssi::TextUI::Line line
|
||||
PREINIT:
|
||||
HV *hv;
|
||||
AV *av;
|
||||
LINE_REC *l;
|
||||
TEXT_BUFFER_FORMAT_REC *f;
|
||||
int i;
|
||||
PPCODE:
|
||||
hv = newHV();
|
||||
l = line->line;
|
||||
if (l->info.format != NULL) {
|
||||
f = l->info.format;
|
||||
(void) hv_store(hv, "module", 6, new_pv(f->module), 0);
|
||||
(void) hv_store(hv, "format", 6, new_pv(f->format), 0);
|
||||
(void) hv_store(hv, "server_tag", 10, new_pv(f->server_tag), 0);
|
||||
(void) hv_store(hv, "target", 6, new_pv(f->target), 0);
|
||||
(void) hv_store(hv, "nick", 4, new_pv(f->nick), 0);
|
||||
av = newAV();
|
||||
for (i = 0; i < f->nargs; i++) {
|
||||
av_push(av, new_pv(f->args[i]));
|
||||
}
|
||||
(void) hv_store(hv, "args", 4, newRV_noinc((SV *) av), 0);
|
||||
} else {
|
||||
(void) hv_store(hv, "text", 4, new_pv(l->info.text), 0);
|
||||
}
|
||||
XPUSHs(sv_2mortal(newRV_noinc((SV *) hv)));
|
||||
|
@ -1,5 +1,6 @@
|
||||
#define PERL_NO_GET_CONTEXT
|
||||
#include "module.h"
|
||||
#include "wrapper_buffer_line.h"
|
||||
|
||||
MODULE = Irssi::TextUI::TextBufferView PACKAGE = Irssi::TextUI::TextBuffer PREFIX = textbuffer_
|
||||
PROTOTYPES: ENABLE
|
||||
@ -33,6 +34,10 @@ textbuffer_view_clear(view)
|
||||
Irssi::TextUI::Line
|
||||
textbuffer_view_get_lines(view)
|
||||
Irssi::TextUI::TextBufferView view
|
||||
CODE:
|
||||
RETVAL = perl_wrap_buffer_line(view->buffer, textbuffer_view_get_lines(view));
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
void
|
||||
textbuffer_view_scroll(view, lines)
|
||||
@ -43,16 +48,24 @@ void
|
||||
textbuffer_view_scroll_line(view, line)
|
||||
Irssi::TextUI::TextBufferView view
|
||||
Irssi::TextUI::Line line
|
||||
CODE:
|
||||
textbuffer_view_scroll_line(view, line->line);
|
||||
|
||||
Irssi::TextUI::LineCache
|
||||
textbuffer_view_get_line_cache(view, line)
|
||||
Irssi::TextUI::TextBufferView view
|
||||
Irssi::TextUI::Line line
|
||||
CODE:
|
||||
RETVAL = textbuffer_view_get_line_cache(view, line->line);
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
void
|
||||
textbuffer_view_remove_line(view, line)
|
||||
Irssi::TextUI::TextBufferView view
|
||||
Irssi::TextUI::Line line
|
||||
CODE:
|
||||
textbuffer_view_remove_line(view, line->line);
|
||||
|
||||
void
|
||||
textbuffer_view_remove_all_lines(view)
|
||||
@ -68,6 +81,8 @@ textbuffer_view_set_bookmark(view, name, line)
|
||||
Irssi::TextUI::TextBufferView view
|
||||
char *name
|
||||
Irssi::TextUI::Line line
|
||||
CODE:
|
||||
textbuffer_view_set_bookmark(view, name, line->line);
|
||||
|
||||
void
|
||||
textbuffer_view_set_bookmark_bottom(view, name)
|
||||
@ -78,6 +93,10 @@ Irssi::TextUI::Line
|
||||
textbuffer_view_get_bookmark(view, name)
|
||||
Irssi::TextUI::TextBufferView view
|
||||
char *name
|
||||
CODE:
|
||||
RETVAL = perl_wrap_buffer_line(view->buffer, textbuffer_view_get_bookmark(view, name));
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
void
|
||||
textbuffer_view_redraw(view)
|
||||
|
@ -1,11 +1,17 @@
|
||||
#define PERL_NO_GET_CONTEXT
|
||||
#include "module.h"
|
||||
#include "wrapper_buffer_line.h"
|
||||
|
||||
void perl_statusbar_init(void);
|
||||
void perl_statusbar_deinit(void);
|
||||
|
||||
static int initialized = FALSE;
|
||||
|
||||
static SV *buffer_line_bless(TEXT_BUFFER_REC *buffer, LINE_REC *line)
|
||||
{
|
||||
return perl_buffer_line_bless(perl_wrap_buffer_line(buffer, line));
|
||||
}
|
||||
|
||||
static void perl_main_window_fill_hash(HV *hv, MAIN_WINDOW_REC *window)
|
||||
{
|
||||
(void) hv_store(hv, "active", 6, plain_bless(window->active, "Irssi::UI::Window"), 0);
|
||||
@ -20,9 +26,9 @@ static void perl_main_window_fill_hash(HV *hv, MAIN_WINDOW_REC *window)
|
||||
|
||||
static void perl_text_buffer_fill_hash(HV *hv, TEXT_BUFFER_REC *buffer)
|
||||
{
|
||||
(void) hv_store(hv, "first_line", 10, plain_bless(buffer->first_line, "Irssi::TextUI::Line"), 0);
|
||||
(void) hv_store(hv, "first_line", 10, buffer_line_bless(buffer, buffer->first_line), 0);
|
||||
(void) hv_store(hv, "lines_count", 11, newSViv(buffer->lines_count), 0);
|
||||
(void) hv_store(hv, "cur_line", 8, plain_bless(buffer->cur_line, "Irssi::TextUI::Line"), 0);
|
||||
(void) hv_store(hv, "cur_line", 8, buffer_line_bless(buffer, buffer->cur_line), 0);
|
||||
(void) hv_store(hv, "last_eol", 8, newSViv(buffer->last_eol), 0);
|
||||
}
|
||||
|
||||
@ -38,20 +44,22 @@ static void perl_text_buffer_view_fill_hash(HV *hv, TEXT_BUFFER_VIEW_REC *view)
|
||||
|
||||
(void) hv_store(hv, "ypos", 4, newSViv(view->ypos), 0);
|
||||
|
||||
(void) hv_store(hv, "startline", 9, plain_bless(view->startline, "Irssi::TextUI::Line"), 0);
|
||||
(void) hv_store(hv, "startline", 9, buffer_line_bless(view->buffer, view->startline), 0);
|
||||
(void) hv_store(hv, "subline", 7, newSViv(view->subline), 0);
|
||||
(void) hv_store(hv, "hidden_level", 12, newSViv(view->hidden_level), 0);
|
||||
|
||||
(void) hv_store(hv, "bottom_startline", 16, plain_bless(view->bottom_startline, "Irssi::TextUI::Line"), 0);
|
||||
(void) hv_store(hv, "bottom_startline", 16,
|
||||
buffer_line_bless(view->buffer, view->bottom_startline), 0);
|
||||
(void) hv_store(hv, "bottom_subline", 14, newSViv(view->bottom_subline), 0);
|
||||
|
||||
(void) hv_store(hv, "empty_linecount", 15, newSViv(view->empty_linecount), 0);
|
||||
(void) hv_store(hv, "bottom", 6, newSViv(view->bottom), 0);
|
||||
}
|
||||
|
||||
static void perl_line_fill_hash(HV *hv, LINE_REC *line)
|
||||
static void perl_line_fill_hash(HV *hv, struct Buffer_Line_Wrapper *line)
|
||||
{
|
||||
(void) hv_store(hv, "info", 4, plain_bless(&line->info, "Irssi::TextUI::LineInfo"), 0);
|
||||
(void) hv_store(hv, "info", 4, plain_bless(&Line(line)->info, "Irssi::TextUI::LineInfo"),
|
||||
0);
|
||||
}
|
||||
|
||||
static void perl_line_cache_fill_hash(HV *hv, LINE_CACHE_REC *cache)
|
||||
@ -242,7 +250,7 @@ CODE:
|
||||
format_create_dest(&dest, NULL, NULL, level, window);
|
||||
text = format_string_expand(str, NULL);
|
||||
text2 = g_strconcat(text, "\n", NULL);
|
||||
gui_printtext_after_time(&dest, prev, text2, time);
|
||||
gui_printtext_after_time(&dest, Line(prev), text2, time);
|
||||
g_free(text);
|
||||
g_free(text2);
|
||||
|
||||
@ -257,13 +265,14 @@ PREINIT:
|
||||
TEXT_DEST_REC dest;
|
||||
CODE:
|
||||
format_create_dest(&dest, NULL, NULL, level, window);
|
||||
gui_printtext_after_time(&dest, prev, str, time);
|
||||
gui_printtext_after_time(&dest, Line(prev), str, time);
|
||||
|
||||
Irssi::TextUI::Line
|
||||
last_line_insert(window)
|
||||
Irssi::UI::Window window
|
||||
CODE:
|
||||
RETVAL = WINDOW_GUI(window)->insert_after;
|
||||
RETVAL = perl_wrap_buffer_line(WINDOW_GUI(window)->view->buffer,
|
||||
WINDOW_GUI(window)->insert_after);
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
@ -281,7 +290,7 @@ PREINIT:
|
||||
TEXT_DEST_REC dest;
|
||||
CODE:
|
||||
format_create_dest(&dest, server, target, level, NULL);
|
||||
gui_printtext_after_time(&dest, prev, str, time);
|
||||
gui_printtext_after_time(&dest, Line(prev), str, time);
|
||||
|
||||
BOOT:
|
||||
irssi_boot(TextUI__Statusbar);
|
||||
|
@ -11,7 +11,7 @@
|
||||
typedef MAIN_WINDOW_REC *Irssi__TextUI__MainWindow;
|
||||
typedef TEXT_BUFFER_REC *Irssi__TextUI__TextBuffer;
|
||||
typedef TEXT_BUFFER_VIEW_REC *Irssi__TextUI__TextBufferView;
|
||||
typedef LINE_REC *Irssi__TextUI__Line;
|
||||
typedef struct Buffer_Line_Wrapper *Irssi__TextUI__Line;
|
||||
typedef LINE_CACHE_REC *Irssi__TextUI__LineCache;
|
||||
typedef LINE_INFO_REC *Irssi__TextUI__LineInfo;
|
||||
typedef SBAR_ITEM_REC *Irssi__TextUI__StatusbarItem;
|
||||
|
@ -2,7 +2,7 @@ TYPEMAP
|
||||
Irssi::TextUI::MainWindow T_PlainObj
|
||||
Irssi::TextUI::TextBuffer T_PlainObj
|
||||
Irssi::TextUI::TextBufferView T_PlainObj
|
||||
Irssi::TextUI::Line T_PlainObj
|
||||
Irssi::TextUI::Line T_BufferLineWrapper
|
||||
Irssi::TextUI::LineCache T_PlainObj
|
||||
Irssi::TextUI::LineInfo T_PlainObj
|
||||
Irssi::TextUI::StatusbarItem T_PlainObj
|
||||
@ -12,8 +12,13 @@ INPUT
|
||||
T_PlainObj
|
||||
$var = irssi_ref_object($arg)
|
||||
|
||||
T_BufferLineWrapper
|
||||
$var = irssi_ref_buffer_line_wrap($arg)
|
||||
|
||||
OUTPUT
|
||||
|
||||
T_PlainObj
|
||||
$arg = plain_bless($var, \"$type\");
|
||||
|
||||
T_BufferLineWrapper
|
||||
$arg = perl_buffer_line_bless($var);
|
||||
|
90
src/perl/textui/wrapper_buffer_line.h
Normal file
90
src/perl/textui/wrapper_buffer_line.h
Normal file
@ -0,0 +1,90 @@
|
||||
#ifndef IRSSI_PERL_TEXTUI_WRAPPER_BUFFER_LINE_H
|
||||
#define IRSSI_PERL_TEXTUI_WRAPPER_BUFFER_LINE_H
|
||||
|
||||
/* This Buffer_Line_Wrapper is a compatibility shim so that the Perl
|
||||
* API does not change in Irssi ABI 24 even though the C API was
|
||||
* changed. That way scripts can continue to work unchanged. */
|
||||
|
||||
struct Buffer_Line_Wrapper {
|
||||
LINE_REC *line;
|
||||
TEXT_BUFFER_REC *buffer;
|
||||
};
|
||||
|
||||
#define Line(wrapper) ((wrapper) == NULL ? NULL : (wrapper)->line)
|
||||
|
||||
static int magic_free_buffer_line(pTHX_ SV *sv, MAGIC *mg)
|
||||
{
|
||||
struct Buffer_Line_Wrapper *wrap = (struct Buffer_Line_Wrapper *) mg->mg_ptr;
|
||||
g_free(wrap);
|
||||
mg->mg_ptr = NULL;
|
||||
sv_setiv(sv, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static MGVTBL vtbl_free_buffer_line = { NULL, NULL, NULL, NULL, magic_free_buffer_line };
|
||||
|
||||
static struct Buffer_Line_Wrapper *perl_wrap_buffer_line(TEXT_BUFFER_REC *buffer, LINE_REC *line)
|
||||
{
|
||||
struct Buffer_Line_Wrapper *wrap;
|
||||
|
||||
if (line == NULL)
|
||||
return NULL;
|
||||
|
||||
wrap = g_new0(struct Buffer_Line_Wrapper, 1);
|
||||
wrap->buffer = buffer;
|
||||
wrap->line = line;
|
||||
|
||||
return wrap;
|
||||
}
|
||||
|
||||
/* This function is more or less a copy of plain_bless, but with a
|
||||
special divertion to put the wrapper in _wrapper and the original
|
||||
line pointer in _irssi, in order to stay compatible with signals
|
||||
and scripts */
|
||||
static SV *perl_buffer_line_bless(struct Buffer_Line_Wrapper *object)
|
||||
{
|
||||
SV *ret, **tmp;
|
||||
HV *hv;
|
||||
const char *stash = "Irssi::TextUI::Line";
|
||||
|
||||
if (object == NULL)
|
||||
return &PL_sv_undef;
|
||||
|
||||
ret = irssi_bless_plain(stash, object);
|
||||
hv = hvref(ret);
|
||||
|
||||
tmp = hv_fetch(hv, "_irssi", 6, 0);
|
||||
|
||||
sv_magic(*tmp, NULL, '~', NULL, 0);
|
||||
|
||||
SvMAGIC(*tmp)->mg_private = 0x1551; /* HF */
|
||||
SvMAGIC(*tmp)->mg_virtual = &vtbl_free_buffer_line;
|
||||
SvMAGIC(*tmp)->mg_ptr = (char *) object;
|
||||
|
||||
(void) hv_store(hv, "_wrapper", 8, *tmp, 0);
|
||||
/* We have to put the Line Pointer in _irssi, not the
|
||||
compatibility wrapper */
|
||||
*tmp = newSViv((IV) object->line);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* This function is a copy of irssi_ref_object, but looking up the
|
||||
wrapper object in _wrapper instead */
|
||||
static void *irssi_ref_buffer_line_wrap(SV *o)
|
||||
{
|
||||
SV **sv;
|
||||
HV *hv;
|
||||
void *p;
|
||||
|
||||
hv = hvref(o);
|
||||
if (hv == NULL)
|
||||
return NULL;
|
||||
|
||||
sv = hv_fetch(hv, "_wrapper", 8, 0);
|
||||
if (sv == NULL)
|
||||
croak("variable is damaged");
|
||||
p = GINT_TO_POINTER(SvIV(*sv));
|
||||
return p;
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user