#############################################################################
## Name: XS/EventFilter.xsp
## Purpose: XS++ for wxEventFilter class
## Author: Mark Dootson
## Modified by:
## Created: 2012-09-26
## RCS-ID: $Id:$
## Copyright: (c) 2012 Mark Dootson
## Licence: This program is free software; you can redistribute it and/or
## modify it under the same terms as Perl itself
#############################################################################
%module{Wx};
%file{xspp/eventfilter.h};
%{
class wxPlEventFilter : public wxEventFilter
{
WXPLI_DECLARE_V_CBACK();
public:
wxPlEventFilter( const char* package )
: wxEventFilter(),
m_callback( "Wx::EventFilter" )
{
dTHX;
m_callback.SetSelf( wxPli_non_object_2_sv(aTHX_ sv_newmortal(), this, package ), true );
}
virtual int FilterEvent(wxEvent& event)
{
dTHX;
if( wxPliFCback( aTHX_ &m_callback, "FilterEvent" ) )
{
// code from e_cback.h
dSP;
ENTER;
SAVETMPS;
int retval;
{
wxPliGuard guard;
SV* e = 0;
SV* rv = 0;
wxClassInfo *ci = event.GetClassInfo();
const wxChar* classname = ci->GetClassName();
if( wcsncmp( classname, wxT("wxPl"), 4 ) == 0 )
{
wxPliClassInfo* cci = (wxPliClassInfo*)ci;
wxPliSelfRef* sr = cci->m_func( &event );
if( sr )
{
// this needs to have the refcount incremented, otherwise
// the refcount will be decremented one time too much when
// exiting from the handler
e = sv_2mortal( newRV_inc( SvRV( sr->m_self ) ) );
}
}
if( !e )
{
char buffer[WXPL_BUF_SIZE];
const char* CLASS = wxPli_cpp_class_2_perl( classname, buffer );
e = sv_newmortal();
sv_setref_pv( e, CHAR_P CLASS, &event );
rv = SvRV( e );
// corner case: prevent destruction if referrer is
// destroyed
SvREFCNT_inc( rv );
sv_2mortal( rv );
guard.SetSV( rv );
wxPli_thread_sv_register( aTHX_ CLASS, &event, e );
}
PUSHMARK( SP );
XPUSHs( m_callback.GetSelf() );
XPUSHs( e );
PUTBACK;
SV* method = sv_2mortal( newRV_inc( (SV*) m_callback.GetMethod() ) );
call_sv( method, G_SCALAR );
SPAGAIN;
retval = POPi;
}
PUTBACK;
FREETMPS;
LEAVE;
return retval;
}
else
return -1; // constant Event_Skip
}
};
%}
%file{-};
#if WXPERL_W_VERSION_GE( 2, 9, 3 )
#include <wx/eventfilter.h>
#include "cpp/e_cback.h"
#include "xspp/eventfilter.h"
%typemap{wxPlEventFilter*}{simple};
%typemap{wxEventFilter*}{simple};
%typemap{wxEvent*}{simple};
%name{Wx::EventFilter} class wxEventFilter
{
%{
static void
wxEventFilter::CLONE()
CODE:
wxPli_thread_sv_clone( aTHX_ CLASS, (wxPliCloneSV)wxPli_detach_object );
%}
public:
%name{Destroy} virtual ~wxEventFilter()
%code%{ wxPli_thread_sv_unregister( aTHX_ "Wx::EventFilter", THIS, ST(0) );
delete THIS;
%};
virtual int FilterEvent(wxEvent* event)
%code%{ RETVAL = -1; %};
};
%name{Wx::PlEventFilter} class wxPlEventFilter : public %name{Wx::EventFilter} wxEventFilter
{
public:
wxPlEventFilter()
%code{% RETVAL = new wxPlEventFilter( CLASS ); %};
};
#endif