Add libwx-perl
[pkg-perl] / deb-src / libwx-perl / libwx-perl-0.96 / cpp / v_cback.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        cpp/v_cback.cpp
3 // Purpose:     implementation for v_cback.h
4 // Author:      Mattia Barbon
5 // Modified by:
6 // Created:     29/10/2000
7 // RCS-ID:      $Id: v_cback.cpp 2057 2007-06-18 23:03:00Z mbarbon $
8 // Copyright:   (c) 2000-2002, 2004 Mattia Barbon
9 // Licence:     This program is free software; you can redistribute it and/or
10 //              modify it under the same terms as Perl itself
11 /////////////////////////////////////////////////////////////////////////////
12
13 bool wxPliVirtualCallback::FindCallback( pTHX_ const char* name ) const
14 {
15     // it would be better to declare m_method & m_stash 'mutable'
16     // but of course some C++ compiler don't support it...
17     CV** pm_method = (CV**)&m_method;
18     HV** pm_stash  = (HV**)&m_stash;
19
20     HV* pkg = 0;
21
22     *pm_method = 0;
23
24     pkg = SvSTASH( SvRV( m_self ) );
25
26     void* p_method = 0;
27
28     if( pkg ) 
29     {
30         GV* gv = gv_fetchmethod( pkg, CHAR_P name );
31         if( gv && isGV( gv ) )
32             // mortal, since CallCallback is called before we return to perl
33             *pm_method = (CV*) ( p_method = GvCV( gv ) );
34     }
35
36     if( !m_method )
37         return false;
38
39     if( !m_stash )
40         *pm_stash = gv_stashpv( CHAR_P m_package, false );
41   
42     if( !m_stash )
43         return true;
44
45     void* p_pmethod = 0;
46
47     GV* gv = gv_fetchmethod( m_stash, CHAR_P name );
48     if( gv && isGV( gv ) )
49         p_pmethod = GvCV( gv );
50   
51     return p_method != p_pmethod;
52 }
53
54 SV* wxPliVirtualCallback::CallCallback( pTHX_ I32 flags, const char* argtypes,
55                                         va_list& arglist ) const
56 {
57     if( !m_method )
58         return 0;
59   
60     dSP;
61
62     ENTER;
63     SAVETMPS;
64
65     PUSHMARK( SP );
66     XPUSHs( m_self );
67     wxPli_push_args( aTHX_ &SP, argtypes, arglist );
68     PUTBACK;
69
70     SV* method = sv_2mortal( newRV_inc( (SV*) m_method ) );
71     call_sv( method, flags );
72
73     SV* retval;
74
75     if( ( flags & G_DISCARD ) == 0 ) {
76         SPAGAIN;
77
78         retval = POPs;
79         SvREFCNT_inc( retval );
80
81         PUTBACK;
82     } else
83         retval = 0;
84
85     FREETMPS;
86     LEAVE;
87
88     return retval;
89 }
90
91 bool wxPliVirtualCallback_FindCallback( pTHX_ const wxPliVirtualCallback* cb,
92                                         const char* name )
93 {
94     return cb->FindCallback( aTHX_ name );
95 }
96
97 SV* wxPliVirtualCallback_CallCallback( pTHX_ const wxPliVirtualCallback* cb,
98                                        I32 flags,
99                                        const char* argtypes, ... )
100 {
101     va_list arglist;
102     va_start( arglist, argtypes );
103
104     SV* ret = cb->CallCallback( aTHX_ flags, argtypes, arglist );
105     
106     va_end( arglist );
107
108     return ret;
109 }
110
111 // Local variables: //
112 // mode: c++ //
113 // End: //