Add libwx-perl
[pkg-perl] / deb-src / libwx-perl / libwx-perl-0.96 / cpp / helpers.h
1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        cpp/helpers.h
3 // Purpose:     some helper functions/classes
4 // Author:      Mattia Barbon
5 // Modified by:
6 // Created:     29/10/2000
7 // RCS-ID:      $Id: helpers.h 2526 2009-02-07 14:35:21Z mbarbon $
8 // Copyright:   (c) 2000-2009 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 #ifndef __CPP_HELPERS_H
14 #define __CPP_HELPERS_H
15
16 #include <wx/object.h>
17 #include <wx/list.h>
18 #include <wx/gdicmn.h>
19 #include <wx/variant.h>
20
21 #include <wx/dynarray.h>
22 #include <wx/arrstr.h>
23
24 class wxPliUserDataCD;
25 class wxPliTreeItemData;
26 struct wxPliEventDescription;
27
28 #ifndef WXDLLIMPEXP_FWD_CORE
29 #define WXDLLIMPEXP_FWD_CORE WXDLLEXPORT
30 #endif
31
32 // forward declare Wx_*Stream
33 class WXDLLIMPEXP_FWD_CORE wxInputStream;
34 class WXDLLIMPEXP_FWD_CORE wxOutputStream;
35 class WXDLLIMPEXP_FWD_CORE wxEvtHandler;
36 class WXDLLIMPEXP_FWD_CORE wxClientDataContainer;
37 class WXDLLIMPEXP_FWD_CORE wxPoint2DDouble;
38 typedef wxInputStream Wx_InputStream;
39 typedef wxOutputStream Wx_OutputStream;
40 typedef const char* PlClassName; // for typemap
41
42 #include <stdarg.h>
43
44 I32 my_looks_like_number( pTHX_ SV* sv );
45
46 // helpers for UTF8 <-> wxString/wxChar
47 // because xsubpp does not allow preprocessor commands in typemaps
48
49 SV* wxPli_wxChar_2_sv( pTHX_ const wxChar* str, SV* out );
50 SV* wxPli_wxString_2_sv( pTHX_ const wxString& str, SV* out );
51
52 #if defined(wxUSE_UNICODE_UTF8) && wxUSE_UNICODE_UTF8
53
54 inline SV* wxPli_wxChar_2_sv( pTHX_ const wxChar* str, SV* out )
55 {
56     sv_setpv( out, wxString( str ).wx_str() );
57     SvUTF8_on( out );
58
59     return out;
60 }
61
62 inline SV* wxPli_wxString_2_sv( pTHX_ const wxString& str, SV* out )
63 {
64     sv_setpv( out, str.wx_str() );
65     SvUTF8_on( out );
66
67     return out;
68 }
69
70 #define WXCHAR_INPUT( var, type, arg ) \
71   const wxWCharBuffer var##_tmp = ( SvUTF8( arg ) ) ? \
72             ( wxString( SvPVutf8_nolen( arg ), wxConvUTF8 ) ).wc_str() \
73           : ( wxString( SvPV_nolen( arg ), wxConvLibc ) ).wc_str(); \
74   var = const_cast<type>( var##_tmp.data() );
75
76 #define WXCHAR_OUTPUT( var, arg ) \
77   wxPli_wxChar_2_sv( aTHX_ var, arg )
78
79 #define WXSTRING_INPUT( var, type, arg ) \
80   var =  ( SvUTF8( arg ) ) ? \
81            wxString( SvPVutf8_nolen( arg ), wxConvUTF8 ) \
82          : wxString( SvPV_nolen( arg ), wxConvLibc );
83
84 #define WXSTRING_OUTPUT( var, arg ) \
85   wxPli_wxString_2_sv( aTHX_ var, arg )
86
87 #elif wxUSE_UNICODE
88
89 inline SV* wxPli_wxChar_2_sv( pTHX_ const wxChar* str, SV* out )
90 {
91     sv_setpv( out, wxConvUTF8.cWC2MB( str ? str : wxEmptyString ) );
92     SvUTF8_on( out );
93
94     return out;
95 }
96
97 inline SV* wxPli_wxString_2_sv( pTHX_ const wxString& str, SV* out )
98 {
99     sv_setpv( out, str.mb_str( wxConvUTF8 ) );
100     SvUTF8_on( out );
101
102     return out;
103 }
104
105 #define WXCHAR_INPUT( var, type, arg ) \
106   const wxString var##_tmp = ( SvUTF8( arg ) ) ? \
107             ( wxString( SvPVutf8_nolen( arg ), wxConvUTF8 ) ) \
108           : ( wxString( SvPV_nolen( arg ), wxConvLibc ) ); \
109   var = const_cast<type>( static_cast<const type>( var##_tmp.wc_str() ) );
110
111 #define WXCHAR_OUTPUT( var, arg ) \
112   wxPli_wxChar_2_sv( aTHX_ var, arg )
113
114 #define WXSTRING_INPUT( var, type, arg ) \
115   var =  ( SvUTF8( arg ) ) ? \
116            wxString( SvPVutf8_nolen( arg ), wxConvUTF8 ) \
117          : wxString( SvPV_nolen( arg ), wxConvLibc );
118
119 #define WXSTRING_OUTPUT( var, arg ) \
120   wxPli_wxString_2_sv( aTHX_ var, arg )
121
122 #else
123
124 #if NEEDS_PLI_HELPERS_STRUCT()
125 bool* wxPli_always_utf8;
126 #else
127 extern bool wxPli_always_utf8;
128 #endif
129
130 inline SV* wxPli_wxChar_2_sv( pTHX_ const wxChar* str, SV* out )
131 {
132 #if NEEDS_PLI_HELPERS_STRUCT()
133     if( *wxPli_always_utf8 )
134 #else
135     if( wxPli_always_utf8 )
136 #endif
137     {
138         sv_setpv( out, wxConvUTF8.cWC2MB( wxConvLibc.cWX2WC( str ? str : wxEmptyString ) ) );
139         SvUTF8_on( out );
140     }
141     else
142     {
143         sv_setpv( out, str );
144     }
145
146     return out;
147 }
148
149 inline SV* wxPli_wxString_2_sv( pTHX_ const wxString& str, SV* out )
150 {
151 #if NEEDS_PLI_HELPERS_STRUCT()
152     if( *wxPli_always_utf8 )
153 #else
154     if( wxPli_always_utf8 )
155 #endif
156     {
157         sv_setpv( out, wxConvUTF8.cWC2MB( wxConvLibc.cWX2WC( str.c_str() ) ) );
158         SvUTF8_on( out );
159     }
160     else
161     {
162         sv_setpvn( out, str.c_str(), str.size() );
163     }
164
165     return out;
166 }
167
168 #define WXCHAR_INPUT( var, type, arg ) \
169   const wxString var##_tmp = ( SvUTF8( arg ) ) ? \
170             ( wxString( wxConvUTF8.cMB2WC( SvPVutf8_nolen( arg ) ), wxConvLocal ) ) \
171           : ( wxString( SvPV_nolen( arg ) ) ); \
172   var = const_cast<type>( static_cast<const type>( var##_tmp.c_str() ) );
173
174 #define WXCHAR_OUTPUT( var, arg ) \
175   wxPli_wxChar_2_sv( aTHX_ var, arg )
176
177 #define WXSTRING_INPUT( var, type, arg ) \
178   var =  ( SvUTF8( arg ) ) ? \
179            wxString( wxConvUTF8.cMB2WC( SvPVutf8_nolen( arg ) ), wxConvLocal ) \
180          : wxString( SvPV_nolen( arg ) );
181
182 #define WXSTRING_OUTPUT( var, arg ) \
183   wxPli_wxString_2_sv( aTHX_ var, arg )
184
185 #endif
186
187 inline wxString wxPli_sv_2_wxString( pTHX_ SV* sv )
188 {
189     wxString ret;
190     WXSTRING_INPUT( ret, wxString , sv );
191
192     return ret;
193 }
194
195 // some utility functions
196
197 inline AV* wxPli_avref_2_av( SV* sv )
198 {
199     if( SvROK( sv ) )
200     {
201         SV* rv = SvRV( sv );
202         return SvTYPE( rv ) == SVt_PVAV ? (AV*)rv : NULL;
203     }
204
205     return NULL;
206 }
207
208 #define wxPli_push_2ints( i1, i2 ) \
209     EXTEND( SP, 2 );                                                         \
210     PUSHs( sv_2mortal( newSViv( (IV) (i1) ) ) );                             \
211     PUSHs( sv_2mortal( newSViv( (IV) (i2) ) ) );                             \
212
213 //
214
215 const int WXPL_BUF_SIZE = 120;
216 const char* FUNCPTR( wxPli_cpp_class_2_perl )( const wxChar* className,
217                                                char buffer[WXPL_BUF_SIZE] );
218 // argtypes is a string; each character describes the C++ argument
219 // type and how it should be used (i.e. a valid string is "ii", assuming
220 // you pass two integers as additional parameters
221 // b - a boolean value
222 // i - an 'int' value
223 // I - an 'unsigned int' value
224 // l - a 'long' value
225 // L - an 'unsigned long' value
226 // d - a 'double' value
227 // p - a char*
228 // w - a wxChar*
229 // P - a wxString*
230 // S - an SV*; a _COPY_ of the SV is passed
231 // s - an SV*; _the SV_ is passed (any modifications made by the function
232 //             will affect the SV, unlike in the previous case)
233 // O - a wxObject*; this will use wxPli_object_2_sv and push the result
234 // o - a void* followed by a char*; will use wxPli_non_object_2_sv
235 //     and push the result
236 // Q, q - same as O and o, but does not call delete() on the object
237 void FUNCPTR( wxPli_push_arguments )( pTHX_ SV*** stack,
238                                       const char* argtypes, ... );
239 void wxPli_push_args( pTHX_ SV*** stack, const char* argtypes, va_list &list );
240
241 void* FUNCPTR( wxPli_sv_2_object )( pTHX_ SV* scalar, const char* classname );
242 SV* FUNCPTR( wxPli_object_2_sv )( pTHX_ SV* var, const wxObject* object );
243 SV* FUNCPTR( wxPli_clientdatacontainer_2_sv )( pTHX_ SV* var,
244                                                wxClientDataContainer* cdc,
245                                                const char* klass );
246 SV* FUNCPTR( wxPli_evthandler_2_sv )( pTHX_ SV* var, wxEvtHandler* evth );
247 SV* FUNCPTR( wxPli_non_object_2_sv )( pTHX_ SV* var, const void* data,
248                                       const char* package );
249
250 SV* FUNCPTR( wxPli_make_object )( void* object, const char* cname );
251 SV* FUNCPTR( wxPli_create_evthandler )( pTHX_ wxEvtHandler* object,
252                                         const char* classn );
253
254 bool FUNCPTR( wxPli_object_is_deleteable )( pTHX_ SV* object );
255 void FUNCPTR( wxPli_object_set_deleteable )( pTHX_ SV* object,
256                                              bool deleteable );
257 // in both attach and detach, object is a _reference_ to a
258 // blessed thing
259 void FUNCPTR( wxPli_attach_object )( pTHX_ SV* object, void* ptr );
260 void* FUNCPTR( wxPli_detach_object )( pTHX_ SV* object );
261
262 const char* FUNCPTR( wxPli_get_class )( pTHX_ SV* ref );
263
264 wxWindowID FUNCPTR( wxPli_get_wxwindowid )( pTHX_ SV* var );
265 int FUNCPTR( wxPli_av_2_stringarray )( pTHX_ SV* avref, wxString** array );
266 int wxPli_av_2_charparray( pTHX_ SV* avref, char*** array );
267 int wxPli_av_2_wxcharparray( pTHX_ SV* avref, wxChar*** array );
268 int wxPli_av_2_uchararray( pTHX_ SV* avref, unsigned char** array );
269 int wxPli_av_2_svarray( pTHX_ SV* avref, SV*** array );
270 int FUNCPTR( wxPli_av_2_intarray )( pTHX_ SV* avref, int** array );
271 int wxPli_av_2_userdatacdarray( pTHX_ SV* avref, wxPliUserDataCD*** array );
272 int FUNCPTR( wxPli_av_2_arraystring )( pTHX_ SV* avref, wxArrayString* array );
273 int FUNCPTR( wxPli_av_2_arrayint )( pTHX_ SV* avref, wxArrayInt* array );
274
275 // pushes the elements of the array into the stack
276 // the caller _MUST_ call PUTBACK; before the function
277 // and SPAGAIN; after the function
278 template<class A>
279 void wxPli_non_objarray_push( pTHX_ const A& things, const char* package )
280 {
281     dSP;
282
283     size_t mx = things.GetCount();
284     EXTEND( SP, int(mx) );
285     for( size_t i = 0; i < mx; ++i )
286     {
287         PUSHs( wxPli_non_object_2_sv( aTHX_ sv_newmortal(),
288                                       &things[i], package ) );
289     }
290
291     PUTBACK;
292 }
293
294 void FUNCPTR( wxPli_stringarray_push )( pTHX_ const wxArrayString& strings );
295 void FUNCPTR( wxPli_intarray_push )( pTHX_ const wxArrayInt& ints );
296 #if WXPERL_W_VERSION_GE( 2, 7, 2 )
297 void wxPli_doublearray_push( pTHX_ const wxArrayDouble& doubles );
298 #endif
299 AV* wxPli_stringarray_2_av( pTHX_ const wxArrayString& strings );
300 AV* wxPli_uchararray_2_av( pTHX_ const unsigned char* array, int count );
301 AV* FUNCPTR( wxPli_objlist_2_av )( pTHX_ const wxList& objs );
302 void FUNCPTR( wxPli_objlist_push )( pTHX_ const wxList& objs );
303
304 template<class A, class E>
305 void wxPli_nonobjarray_push( pTHX_ const A& objs, const char* klass )
306 {
307     dSP;
308
309     size_t mx = objs.GetCount();
310     EXTEND( SP, IV(mx) );
311     for( size_t i = 0; i < mx; ++i )
312     {
313         PUSHs( wxPli_non_object_2_sv( aTHX_ sv_newmortal(),
314                new E( objs[i] ), klass ) );
315     }
316
317     PUTBACK;
318 }
319
320 void wxPli_delete_argv( void*** argv, bool unicode );
321 int wxPli_get_args_argc_argv( void*** argv, bool unicode );
322 void wxPli_get_args_objectarray( pTHX_ SV** sp, int items,
323                                          void** array, const char* package );
324
325 wxPoint FUNCPTR( wxPli_sv_2_wxpoint_test )( pTHX_ SV* scalar, bool* ispoint );
326 wxPoint FUNCPTR( wxPli_sv_2_wxpoint )( pTHX_ SV* scalar );
327 wxSize FUNCPTR( wxPli_sv_2_wxsize )( pTHX_ SV* scalar );
328 #if WXPERL_W_VERSION_GE( 2, 6, 0 )
329 class WXDLLIMPEXP_FWD_CORE wxGBPosition; class WXDLLIMPEXP_FWD_CORE wxGBSpan;
330 wxGBPosition wxPli_sv_2_wxgbposition( pTHX_ SV* scalar );
331 wxGBSpan wxPli_sv_2_wxgbspan( pTHX_ SV* scalar );
332 #endif
333 #if WXPERL_W_VERSION_GE( 2, 9, 0 )
334 class wxPosition;
335 wxPosition wxPli_sv_2_wxposition( pTHX_ SV* scalar );
336 wxVariant wxPli_sv_2_wxvariant( pTHX_ SV* scalar );
337 #endif
338
339 wxKeyCode wxPli_sv_2_keycode( pTHX_ SV* scalar );
340
341 #if WXPERL_W_VERSION_GE( 2, 9, 0 )
342 int wxPli_av_2_pointlist( pTHX_ SV* array, wxPointList *points, wxPoint** tmp );
343 #else
344 int wxPli_av_2_pointlist( pTHX_ SV* array, wxList *points, wxPoint** tmp );
345 #endif
346 int wxPli_av_2_pointarray( pTHX_ SV* array, wxPoint** points );
347 int wxPli_av_2_point2ddoublearray( pTHX_ SV* array, wxPoint2DDouble** points );
348
349 template<class E>
350 class wxPliArrayGuard
351 {
352 private:
353     E* m_array;
354 public:
355     wxPliArrayGuard( E* els = NULL ) : m_array( els ) {}
356
357     ~wxPliArrayGuard()
358     {
359         delete[] m_array;
360     }
361
362     E** lvalue() { return &m_array; }
363     E* rvalue() { return m_array; }
364     operator E*() { return m_array; }
365
366     E* disarm()
367     {
368         E* oldvalue = m_array;
369         m_array = NULL;
370
371         return oldvalue;
372     }
373 };
374
375 // thread helpers
376 #if wxPERL_USE_THREADS
377 typedef void (* wxPliCloneSV)( pTHX_ SV* scalar );
378 void FUNCPTR( wxPli_thread_sv_register )( pTHX_ const char* package,
379                                           const void* ptr, SV* sv );
380 void FUNCPTR( wxPli_thread_sv_unregister )( pTHX_ const char* package,
381                                             const void* ptr, SV* sv );
382 void FUNCPTR( wxPli_thread_sv_clone )( pTHX_ const char* package,
383                                        wxPliCloneSV clonefn );
384 #else // if !wxPERL_USE_THREADS
385 #define wxPli_thread_sv_register( package, ptr, sv )
386 #define wxPli_thread_sv_unregister( package, ptr, sv )
387 #define wxPli_thread_sv_clone( package, clonefn )
388 #endif // !wxPERL_USE_THREADS
389
390 // stream wrappers
391 class wxPliInputStream;
392 class wxPliOutputStream;
393 class wxStreamBase;
394
395 void wxPli_sv_2_istream( pTHX_ SV* scalar, wxPliInputStream& stream );
396 void wxPli_sv_2_ostream( pTHX_ SV* scalar, wxPliOutputStream& stream );
397 void FUNCPTR( wxPli_stream_2_sv )( pTHX_ SV* scalar, wxStreamBase* stream,
398                                    const char* package );
399 wxPliInputStream* FUNCPTR( wxPliInputStream_ctor )( SV* sv );
400 wxPliOutputStream* FUNCPTR( wxPliOutputStream_ctor )( SV* sv );
401
402 void FUNCPTR( wxPli_set_events )( const wxPliEventDescription* events );
403
404 // defined in Constants.xs
405 void FUNCPTR( wxPli_add_constant_function )( double (**)( const char*, int ) );
406 void FUNCPTR( wxPli_remove_constant_function )( double (**)( const char*,
407                                                              int ) );
408
409 // defined in v_cback.cpp
410 class wxPliVirtualCallback;
411
412 bool FUNCPTR( wxPliVirtualCallback_FindCallback )
413     ( pTHX_ const wxPliVirtualCallback* cb, const char* name );
414 // see wxPli_push_args for a description of argtypes
415 SV* FUNCPTR( wxPliVirtualCallback_CallCallback )
416     ( pTHX_ const wxPliVirtualCallback* cb, I32 flags,
417       const char* argtypes, ... );
418
419 // defined in overload.cpp
420 struct wxPliPrototype
421 {
422     wxPliPrototype( const char** const t,
423                     const unsigned char* const a,
424                     const size_t c )
425       : tnames( t ), args( a ), count( c ) { }
426
427     const char** const tnames;
428     const unsigned char* const args;
429     const size_t count;
430 };
431
432 bool wxPli_match_arguments( pTHX_ const wxPliPrototype& prototype,
433                             int required = -1,
434                             bool allow_more = false );
435 bool FUNCPTR( wxPli_match_arguments_skipfirst )( pTHX_ const wxPliPrototype& p,
436                                                  int required,
437                                                  bool allow_more );
438
439 #define WXPLI_BOOT_ONCE_( name, xs ) \
440 bool name##_booted = false; \
441 extern "C" XS(wxPli_boot_##name); \
442 extern "C" \
443 xs(boot_##name) \
444 { \
445     if( name##_booted ) return; \
446     name##_booted = true; \
447     wxPli_boot_##name( aTHX_ cv ); \
448 }
449
450 #define WXPLI_BOOT_ONCE( name ) WXPLI_BOOT_ONCE_( name, XS )
451 #if defined(WIN32) || defined(__CYGWIN__)
452 #  define WXPLI_BOOT_ONCE_EXP( name ) WXPLI_BOOT_ONCE_( name, WXXS )
453 #else
454 #  define WXPLI_BOOT_ONCE_EXP WXPLI_BOOT_ONCE
455 #endif
456
457 #if WXPERL_W_VERSION_GE( 2, 5, 1 )
458 #define WXPLI_INIT_CLASSINFO()
459 #else
460 #define WXPLI_INIT_CLASSINFO() \
461   wxClassInfo::CleanUpClasses(); \
462   wxClassInfo::InitializeClasses()
463 #endif
464
465 struct wxPliHelpers
466 {
467     void* ( * m_wxPli_sv_2_object )( pTHX_ SV*, const char* );
468     SV* ( * m_wxPli_evthandler_2_sv )( pTHX_ SV* var, wxEvtHandler* evth );
469     SV* ( * m_wxPli_object_2_sv )( pTHX_ SV*, const wxObject* );
470     SV* ( * m_wxPli_non_object_2_sv )( pTHX_ SV* , const void*, const char* );
471     SV* ( * m_wxPli_make_object )( void*, const char* );
472     wxPoint ( * m_wxPli_sv_2_wxpoint_test )( pTHX_ SV*, bool* );
473     wxPoint ( * m_wxPli_sv_2_wxpoint )( pTHX_ SV* );
474     wxSize ( * m_wxPli_sv_2_wxsize )( pTHX_ SV* );
475     int ( * m_wxPli_av_2_intarray )( pTHX_ SV*, int** );
476     void ( * m_wxPli_stream_2_sv )( pTHX_ SV*, wxStreamBase*, const char* );
477
478     void ( * m_wxPli_add_constant_function )
479         ( double (**)( const char*, int ) );
480     void ( * m_wxPli_remove_constant_function )
481         ( double (**)( const char*, int ) );
482
483     bool ( * m_wxPliVirtualCallback_FindCallback )( pTHX_ 
484                                                    const wxPliVirtualCallback*,
485                                                     const char* );
486     SV* ( * m_wxPliVirtualCallback_CallCallback )
487         ( pTHX_ const wxPliVirtualCallback*, I32,
488           const char*, ... );
489     bool ( * m_wxPli_object_is_deleteable )( pTHX_ SV* );
490     void ( * m_wxPli_object_set_deleteable )( pTHX_ SV*, bool );
491     const char* ( * m_wxPli_get_class )( pTHX_ SV* );
492     wxWindowID ( * m_wxPli_get_wxwindowid )( pTHX_ SV* );
493     int ( * m_wxPli_av_2_stringarray )( pTHX_ SV*, wxString** );
494     wxPliInputStream* ( * m_wxPliInputStream_ctor )( SV* );
495     const char* ( * m_wxPli_cpp_class_2_perl )( const wxChar*,
496                                                 char buffer[WXPL_BUF_SIZE] );
497     void ( * m_wxPli_push_arguments )( pTHX_ SV*** stack,
498                                        const char* argtypes, ... );
499     void ( * m_wxPli_attach_object )( pTHX_ SV* object, void* ptr );
500     void* ( * m_wxPli_detach_object )( pTHX_ SV* object );
501     SV* ( * m_wxPli_create_evthandler )( pTHX_ wxEvtHandler* object,
502                                          const char* cln );
503     bool (* m_wxPli_match_arguments_skipfirst )( pTHX_ const wxPliPrototype&,
504                                                  int required,
505                                                  bool allow_more );
506     AV* (* m_wxPli_objlist_2_av )( pTHX_ const wxList& objs );
507     void (* m_wxPli_intarray_push )( pTHX_ const wxArrayInt& );
508     SV* (* m_wxPli_clientdatacontainer_2_sv )( pTHX_ SV* var,
509                                                wxClientDataContainer* cdc,
510                                                const char* klass );
511 #if wxPERL_USE_THREADS
512     void (* m_wxPli_thread_sv_register )( pTHX_ const char* package,
513                                           const void* ptr, SV* sv );
514     void (* m_wxPli_thread_sv_unregister )( pTHX_ const char* package,
515                                             const void* ptr, SV* sv );
516     void (* m_wxPli_thread_sv_clone )( pTHX_ const char* package,
517                                        wxPliCloneSV clonefn );
518 #endif
519 #if !wxUSE_UNICODE
520     bool *m_wxPli_always_utf8;
521 #endif
522     int (* m_wxPli_av_2_arrayint )( pTHX_ SV* avref, wxArrayInt* array );
523     void (* m_wxPli_set_events )( const wxPliEventDescription* events );
524     int (* m_wxPli_av_2_arraystring )( pTHX_ SV* avref, wxArrayString* array );
525     void (* m_wxPli_objlist_push )( pTHX_ const wxList& objs );
526     wxPliOutputStream* ( * m_wxPliOutputStream_ctor )( SV* );
527     void (* m_wxPli_stringarray_push )( pTHX_ const wxArrayString& );
528 };
529
530 #if wxPERL_USE_THREADS
531 #   define wxDEFINE_PLI_HELPER_THREADS() \
532  &wxPli_thread_sv_register, \
533  &wxPli_thread_sv_unregister, &wxPli_thread_sv_clone,
534 #   define wxINIT_PLI_HELPER_THREADS( name ) \
535   wxPli_thread_sv_register = name->m_wxPli_thread_sv_register; \
536   wxPli_thread_sv_unregister = name->m_wxPli_thread_sv_unregister; \
537   wxPli_thread_sv_clone = name->m_wxPli_thread_sv_clone;
538 #else
539 #   define wxDEFINE_PLI_HELPER_THREADS()
540 #   define wxINIT_PLI_HELPER_THREADS( name )
541 #endif
542
543 #if !wxUSE_UNICODE
544 #   define wxDEFINE_PLI_HELPER_UNICODE() \
545  &wxPli_always_utf8,
546 #   define wxINIT_PLI_HELPER_UNICODE( name ) \
547   wxPli_always_utf8 = name->m_wxPli_always_utf8;
548 #else
549 #   define wxDEFINE_PLI_HELPER_UNICODE()
550 #   define wxINIT_PLI_HELPER_UNICODE( name )
551 #endif
552
553 #define DEFINE_PLI_HELPERS( name ) \
554 wxPliHelpers name = { &wxPli_sv_2_object, \
555  &wxPli_evthandler_2_sv, &wxPli_object_2_sv, \
556  &wxPli_non_object_2_sv, &wxPli_make_object, &wxPli_sv_2_wxpoint_test, \
557  &wxPli_sv_2_wxpoint, \
558  &wxPli_sv_2_wxsize, &wxPli_av_2_intarray, wxPli_stream_2_sv, \
559  &wxPli_add_constant_function, &wxPli_remove_constant_function, \
560  &wxPliVirtualCallback_FindCallback, &wxPliVirtualCallback_CallCallback, \
561  &wxPli_object_is_deleteable, &wxPli_object_set_deleteable, &wxPli_get_class, \
562  &wxPli_get_wxwindowid, &wxPli_av_2_stringarray, &wxPliInputStream_ctor, \
563  &wxPli_cpp_class_2_perl, &wxPli_push_arguments, &wxPli_attach_object, \
564  &wxPli_detach_object, &wxPli_create_evthandler, \
565  &wxPli_match_arguments_skipfirst, &wxPli_objlist_2_av, &wxPli_intarray_push, \
566  &wxPli_clientdatacontainer_2_sv, \
567  wxDEFINE_PLI_HELPER_THREADS() \
568  wxDEFINE_PLI_HELPER_UNICODE() \
569  &wxPli_av_2_arrayint, &wxPli_set_events, &wxPli_av_2_arraystring, \
570  &wxPli_objlist_push, &wxPliOutputStream_ctor, &wxPli_stringarray_push \
571  }
572
573 #if NEEDS_PLI_HELPERS_STRUCT()
574
575 #define INIT_PLI_HELPERS( name ) \
576   SV* wxpli_tmp = get_sv( "Wx::_exports", 1 ); \
577   wxPliHelpers* name = INT2PTR( wxPliHelpers*, SvIV( wxpli_tmp ) ); \
578   wxPli_sv_2_object = name->m_wxPli_sv_2_object; \
579   wxPli_evthandler_2_sv = name->m_wxPli_evthandler_2_sv; \
580   wxPli_object_2_sv = name->m_wxPli_object_2_sv; \
581   wxPli_non_object_2_sv = name->m_wxPli_non_object_2_sv; \
582   wxPli_make_object = name->m_wxPli_make_object; \
583   wxPli_sv_2_wxpoint_test = name->m_wxPli_sv_2_wxpoint_test; \
584   wxPli_sv_2_wxpoint = name->m_wxPli_sv_2_wxpoint; \
585   wxPli_sv_2_wxsize = name->m_wxPli_sv_2_wxsize; \
586   wxPli_av_2_intarray = name->m_wxPli_av_2_intarray; \
587   wxPli_stream_2_sv = name->m_wxPli_stream_2_sv; \
588   wxPli_add_constant_function = name->m_wxPli_add_constant_function; \
589   wxPli_remove_constant_function = name->m_wxPli_remove_constant_function; \
590   wxPliVirtualCallback_FindCallback = name->m_wxPliVirtualCallback_FindCallback; \
591   wxPliVirtualCallback_CallCallback = name->m_wxPliVirtualCallback_CallCallback; \
592   wxPli_object_is_deleteable = name->m_wxPli_object_is_deleteable; \
593   wxPli_object_set_deleteable = name->m_wxPli_object_set_deleteable; \
594   wxPli_get_class = name->m_wxPli_get_class; \
595   wxPli_get_wxwindowid = name->m_wxPli_get_wxwindowid; \
596   wxPli_av_2_stringarray = name->m_wxPli_av_2_stringarray; \
597   wxPliInputStream_ctor = name->m_wxPliInputStream_ctor; \
598   wxPli_cpp_class_2_perl = name->m_wxPli_cpp_class_2_perl; \
599   wxPli_push_arguments = name->m_wxPli_push_arguments; \
600   wxPli_attach_object = name->m_wxPli_attach_object; \
601   wxPli_detach_object = name->m_wxPli_detach_object; \
602   wxPli_create_evthandler = name->m_wxPli_create_evthandler; \
603   wxPli_match_arguments_skipfirst = name->m_wxPli_match_arguments_skipfirst; \
604   wxPli_objlist_2_av = name->m_wxPli_objlist_2_av; \
605   wxPli_intarray_push = name->m_wxPli_intarray_push; \
606   wxPli_clientdatacontainer_2_sv = name->m_wxPli_clientdatacontainer_2_sv; \
607   wxINIT_PLI_HELPER_THREADS( name ) \
608   wxINIT_PLI_HELPER_UNICODE( name ) \
609   wxPli_av_2_arrayint = name->m_wxPli_av_2_arrayint; \
610   wxPli_set_events = name->m_wxPli_set_events; \
611   wxPli_av_2_arraystring = name->m_wxPli_av_2_arraystring; \
612   wxPli_objlist_push = name->m_wxPli_objlist_push; \
613   wxPliOutputStream_ctor = name->m_wxPliOutputStream_ctor; \
614   wxPli_av_2_stringarray = name->m_wxPli_av_2_stringarray; \
615   WXPLI_INIT_CLASSINFO();
616
617 #else
618
619 #define INIT_PLI_HELPERS( name )
620
621 #endif
622
623 int wxCALLBACK ListCtrlCompareFn( long item1, long item2, long comparefn );
624
625 class wxPliUserDataO : public wxObject
626 {
627 public:
628     wxPliUserDataO( SV* data )
629     {
630         dTHX;
631         m_data = data ? newSVsv( data ) : NULL;
632     }
633
634     ~wxPliUserDataO()
635     {
636         dTHX;
637         SvREFCNT_dec( m_data );
638     }
639
640     SV* GetData() { return m_data; }
641 private:
642     SV* m_data;
643 };
644 typedef wxPliUserDataO   Wx_UserDataO;
645
646 class wxPliSelfRef
647 {
648 public:
649     wxPliSelfRef( const char* unused = 0 ) {}
650     virtual ~wxPliSelfRef()
651         { dTHX; if( m_self ) SvREFCNT_dec( m_self ); }
652
653     void SetSelf( SV* self, bool increment = true )
654     {
655         dTHX;
656         m_self = self;
657         if( m_self && increment )       
658             SvREFCNT_inc( m_self );
659     }
660
661     SV* GetSelf() const { return m_self; }
662     void DeleteSelf( bool fromDestroy );
663 public:
664     SV* m_self;
665 };
666
667 typedef wxPliSelfRef* (* wxPliGetCallbackObjectFn)(wxObject* object);
668
669 class wxPliClassInfo : public wxClassInfo
670 {
671 public:
672 #if wxUSE_EXTENDED_RTTI
673     wxPliClassInfo( const wxClassInfo **_Parents,
674                     const wxChar *_ClassName,
675                     int size, wxObjectConstructorFn ctor,
676                     wxPliGetCallbackObjectFn fn )
677         :wxClassInfo( _Parents, NULL, _ClassName, size, ctor, NULL, NULL,
678                       NULL, NULL, 0, NULL, NULL, NULL )
679     {
680         m_func = fn;
681     }
682 #else
683     wxPliClassInfo( wxChar *cName, const wxClassInfo *baseInfo1,
684                     const wxClassInfo *baseInfo2, 
685                     int sz, wxObjectConstructorFn ctor,
686                     wxPliGetCallbackObjectFn fn )
687         :wxClassInfo( cName, baseInfo1, baseInfo2, sz, ctor)
688     {
689         m_func = fn;
690     }
691 #endif
692 public:
693     wxPliGetCallbackObjectFn m_func;
694 };
695
696 #if wxUSE_EXTENDED_RTTI
697 #define WXPLI_DECLARE_DYNAMIC_CLASS(name) \
698 public:\
699   static wxPliClassInfo ms_classInfo;\
700   static const wxClassInfo* ms_classParents[] ;\
701   virtual wxClassInfo *GetClassInfo() const \
702    { return &ms_classInfo; }
703 #else
704 #define WXPLI_DECLARE_DYNAMIC_CLASS(name) \
705 public:\
706   static wxPliClassInfo ms_classInfo;\
707   virtual wxClassInfo *GetClassInfo() const \
708    { return &ms_classInfo; }
709 #endif
710 #define WXPLI_DECLARE_DYNAMIC_CLASS_CTOR(name) \
711   WXPLI_DECLARE_DYNAMIC_CLASS(name) \
712   static wxObject* wxCreateObject()
713
714 #define WXPLI_DECLARE_SELFREF() \
715 public:\
716   wxPliSelfRef m_callback
717
718 #define WXPLI_DECLARE_V_CBACK() \
719 public:\
720   wxPliVirtualCallback m_callback
721
722 #if wxUSE_EXTENDED_RTTI
723 #define WXPLI_IMPLEMENT_DYNAMIC_CLASS_(name, basename, fn)                   \
724     wxPliSelfRef* wxPliGetSelfFor##name(wxObject* object)                    \
725         { return &((name *)object)->m_callback; }                            \
726     const wxClassInfo* name::ms_classParents[] =                             \
727         { &basename::ms_classInfo , NULL };                                  \
728     wxPliClassInfo name::ms_classInfo( ms_classParents,                      \
729         (wxChar *) wxT(#name), (int) sizeof(name), fn,                       \
730         (wxPliGetCallbackObjectFn) wxPliGetSelfFor##name);
731 #else
732 #define WXPLI_IMPLEMENT_DYNAMIC_CLASS_(name, basename, fn)                   \
733     wxPliSelfRef* wxPliGetSelfFor##name(wxObject* object)                    \
734         { return &((name *)object)->m_callback; }                            \
735     wxPliClassInfo name::ms_classInfo((wxChar *) wxT(#name),                 \
736         &basename::ms_classInfo, NULL, (int) sizeof(name), fn,               \
737         (wxPliGetCallbackObjectFn) wxPliGetSelfFor##name);
738 #endif
739 #define WXPLI_IMPLEMENT_DYNAMIC_CLASS(name, basename)                        \
740     WXPLI_IMPLEMENT_DYNAMIC_CLASS_(name, basename, NULL)
741 #define WXPLI_IMPLEMENT_DYNAMIC_CLASS_CTOR(name, basename)                   \
742     WXPLI_IMPLEMENT_DYNAMIC_CLASS_(name, basename, name::wxCreateObject)     \
743     wxObject* name::wxCreateObject() { return new name(); }
744
745 #define WXPLI_DEFAULT_CONSTRUCTOR_NC( name, packagename, incref ) \
746     name( const char* package )                                   \
747         : m_callback( packagename )                               \
748     {                                                             \
749         m_callback.SetSelf( wxPli_make_object( this, package ), incref );\
750     }
751
752 #define WXPLI_DEFAULT_CONSTRUCTOR( name, packagename, incref ) \
753     name( const char* package )                                \
754         :m_callback( packagename )                             \
755     {                                                          \
756         m_callback.SetSelf( wxPli_make_object( this, package ), incref );\
757     }
758
759 #define WXPLI_CONSTRUCTOR_1_NC( name, base, packagename, incref, argt1 ) \
760     name( const char* package, argt1 _arg1 )                       \
761         : base( _arg1 ),                                           \
762           m_callback( packagename )                                \
763     {                                                              \
764         m_callback.SetSelf( wxPli_make_object( this, package ), incref );\
765     }
766
767 #define WXPLI_CONSTRUCTOR_2( name, packagename, incref, argt1, argt2 )     \
768      name( const char* package, argt1 _arg1, argt2 _arg2 )                 \
769          :m_callback( packagename )                                        \
770      {                                                                     \
771          m_callback.SetSelf( wxPli_make_object( this, package ), incref ); \
772          Create( _arg1, _arg2 );                                           \
773      }
774
775 #define WXPLI_CONSTRUCTOR_5( name, packagename, incref, argt1, argt2, argt3, argt4, argt5 ) \
776      name( const char* package, argt1 _arg1, argt2 _arg2, argt3 _arg3,     \
777            argt4 _arg4, argt5 _arg5 )                                      \
778          :m_callback( packagename )                                        \
779      {                                                                     \
780          m_callback.SetSelf( wxPli_make_object( this, package ), incref ); \
781          Create( _arg1, _arg2, _arg3, _arg4, _arg5 );                      \
782      }
783
784 #define WXPLI_CONSTRUCTOR_6( name, packagename, incref, argt1, argt2, argt3, argt4, argt5, argt6 ) \
785      name( const char* package, argt1 _arg1, argt2 _arg2, argt3 _arg3,     \
786            argt4 _arg4, argt5 _arg5, argt6 _arg6 )                          \
787          :m_callback( packagename )                                        \
788      {                                                                     \
789          m_callback.SetSelf( wxPli_make_object( this, package ), incref ); \
790          Create( _arg1, _arg2, _arg3, _arg4, _arg5, _arg6 );               \
791      }
792
793 #define WXPLI_CONSTRUCTOR_7( name, packagename, incref, argt1, argt2, argt3, argt4, argt5, argt6, argt7 ) \
794      name( const char* package, argt1 _arg1, argt2 _arg2, argt3 _arg3,     \
795            argt4 _arg4, argt5 _arg5, argt6 _arg6, argt7 _arg7)             \
796          :m_callback( packagename )                                        \
797      {                                                                     \
798          m_callback.SetSelf( wxPli_make_object( this, package ), incref ); \
799          Create( _arg1, _arg2, _arg3, _arg4, _arg5, _arg6, _arg7 );        \
800      }
801
802 #define WXPLI_CONSTRUCTOR_8( name, packagename, incref, argt1, argt2, argt3, argt4, argt5, argt6, argt7, argt8 ) \
803      name( const char* package, argt1 _arg1, argt2 _arg2, argt3 _arg3,     \
804            argt4 _arg4, argt5 _arg5, argt6 _arg6, argt7 _arg7, argt8 _arg8)\
805          :m_callback( packagename )                                        \
806      {                                                                     \
807          m_callback.SetSelf( wxPli_make_object( this, package ), incref ); \
808          Create( _arg1, _arg2, _arg3, _arg4, _arg5, _arg6, _arg7, _arg8 ); \
809      }
810
811 #define WXPLI_CONSTRUCTOR_9( name, packagename, incref, argt1, argt2, argt3, argt4, argt5, argt6, argt7, argt8, argt9 ) \
812      name( const char* package, argt1 _arg1, argt2 _arg2, argt3 _arg3,     \
813            argt4 _arg4, argt5 _arg5, argt6 _arg6, argt7 _arg7,             \
814            argt8 _arg8, argt9 _arg9 )                                      \
815          :m_callback( packagename )                                        \
816      {                                                                     \
817          m_callback.SetSelf( wxPli_make_object( this, package ), incref ); \
818          Create( _arg1, _arg2, _arg3, _arg4, _arg5, _arg6, _arg7, _arg8,   \
819                  _arg9 );                                                  \
820      }
821
822 #define WXPLI_CONSTRUCTOR_10( name, packagename, incref, argt1, argt2, argt3, argt4, argt5, argt6, argt7, argt8, argt9, argt10 ) \
823      name( const char* package, argt1 _arg1, argt2 _arg2, argt3 _arg3,     \
824            argt4 _arg4, argt5 _arg5, argt6 _arg6, argt7 _arg7,             \
825            argt8 _arg8, argt9 _arg9, argt10 _arg10 )                       \
826          :m_callback( packagename )                                        \
827      {                                                                     \
828          m_callback.SetSelf( wxPli_make_object( this, package ), incref ); \
829          Create( _arg1, _arg2, _arg3, _arg4, _arg5, _arg6, _arg7, _arg8,   \
830                  _arg9, _arg10 );                                          \
831      }
832
833 #define WXPLI_CONSTRUCTOR_11( name, packagename, incref, argt1, argt2, argt3, argt4, argt5, argt6, argt7, argt8, argt9, argt10, argt11 ) \
834      name( const char* package, argt1 _arg1, argt2 _arg2, argt3 _arg3,     \
835            argt4 _arg4, argt5 _arg5, argt6 _arg6, argt7 _arg7,             \
836            argt8 _arg8, argt9 _arg9, argt10 _arg10, argt11 _arg11 )        \
837          :m_callback( packagename )                                        \
838      {                                                                     \
839          m_callback.SetSelf( wxPli_make_object( this, package ), incref ); \
840          Create( _arg1, _arg2, _arg3, _arg4, _arg5, _arg6, _arg7, _arg8,   \
841                  _arg9, _arg10, _arg11 );                                  \
842      }
843
844 #define WXPLI_DECLARE_CLASS_6( name, incref, argt1, argt2, argt3, argt4, argt5, argt6 ) \
845 class wxPli##name:public wx##name                                       \
846 {                                                                       \
847     WXPLI_DECLARE_DYNAMIC_CLASS( wxPli##name );                         \
848     WXPLI_DECLARE_SELFREF();                                            \
849 public:                                                                 \
850     WXPLI_DEFAULT_CONSTRUCTOR( wxPli##name, "Wx::" #name, incref );     \
851     WXPLI_CONSTRUCTOR_6( wxPli##name, "Wx::" #name, incref,             \
852                          argt1, argt2, argt3, argt4, argt5, argt6 );    \
853 };
854
855 #define WXPLI_DECLARE_CLASS_7( name, incref, argt1, argt2, argt3, argt4, argt5, argt6, argt7 ) \
856 class wxPli##name:public wx##name                                       \
857 {                                                                       \
858     WXPLI_DECLARE_DYNAMIC_CLASS( wxPli##name );                         \
859     WXPLI_DECLARE_SELFREF();                                            \
860 public:                                                                 \
861     WXPLI_DEFAULT_CONSTRUCTOR( wxPli##name, "Wx::" #name, incref );     \
862     WXPLI_CONSTRUCTOR_7( wxPli##name, "Wx::" #name, incref,             \
863                          argt1, argt2, argt3, argt4, argt5, argt6,      \
864                          argt7 );                                       \
865 };
866
867 #define WXPLI_DECLARE_CLASS_8( name, incref, argt1, argt2, argt3, argt4, argt5, argt6, argt7, argt8 ) \
868 class wxPli##name:public wx##name                                       \
869 {                                                                       \
870     WXPLI_DECLARE_DYNAMIC_CLASS( wxPli##name );                         \
871     WXPLI_DECLARE_SELFREF();                                            \
872 public:                                                                 \
873     WXPLI_DEFAULT_CONSTRUCTOR( wxPli##name, "Wx::" #name, incref );     \
874     WXPLI_CONSTRUCTOR_8( wxPli##name, "Wx::" #name, incref,             \
875                          argt1, argt2, argt3, argt4, argt5, argt6,      \
876                          argt7, argt8 );                                \
877 };
878
879 #define WXPLI_DECLARE_CLASS_9( name, incref, argt1, argt2, argt3, argt4, argt5, argt6, argt7, argt8, argt9 ) \
880 class wxPli##name:public wx##name                                       \
881 {                                                                       \
882     WXPLI_DECLARE_DYNAMIC_CLASS( wxPli##name );                         \
883     WXPLI_DECLARE_SELFREF();                                            \
884 public:                                                                 \
885     WXPLI_DEFAULT_CONSTRUCTOR( wxPli##name, "Wx::" #name, incref );     \
886     WXPLI_CONSTRUCTOR_9( wxPli##name, "Wx::" #name, incref,             \
887                          argt1, argt2, argt3, argt4, argt5, argt6,      \
888                          argt7, argt8, argt9 );                         \
889 };
890
891 #define WXPLI_DECLARE_CLASS_10( name, incref, argt1, argt2, argt3, argt4, argt5, argt6, argt7, argt8, argt9, argt10 ) \
892 class wxPli##name:public wx##name                                       \
893 {                                                                       \
894     WXPLI_DECLARE_DYNAMIC_CLASS( wxPli##name );                         \
895     WXPLI_DECLARE_SELFREF();                                            \
896 public:                                                                 \
897     WXPLI_DEFAULT_CONSTRUCTOR( wxPli##name, "Wx::" #name, incref );     \
898     WXPLI_CONSTRUCTOR_10( wxPli##name, "Wx::" #name, incref,            \
899                          argt1, argt2, argt3, argt4, argt5, argt6,      \
900                          argt7, argt8, argt9, argt10 );                 \
901 };
902
903
904 #define WXPLI_DEFINE_CLASS( name ) \
905 WXPLI_IMPLEMENT_DYNAMIC_CLASS( wxPli##name, wx##name );
906
907 typedef SV SV_null; // equal to SV except that maps C++ 0 <-> Perl undef
908
909 // helpers for declaring event macros
910 struct wxPliEventDescription
911 {
912     const char* name;
913     // 2 - only THIS and function
914     // 3 - THIS, function, one ID
915     // 4 - THIS, function, two ids
916     // 5 - THIS, function, two ids, event id
917     unsigned char args;
918     int evtID;    
919 };
920
921 #define wxPli_StdEvent( NAME, ARGS )  { #NAME, ARGS, wx##NAME },
922 #define wxPli_Event( NAME, ARGS, ID ) { #NAME, ARGS, ID },
923
924 #endif // __CPP_HELPERS_H
925
926 #if defined( _WX_CLNTDATAH__ )
927 #ifndef __CPP_HELPERS_H_UDCD
928 #define __CPP_HELPERS_H_UDCD
929
930 class wxPliUserDataCD : public wxClientData
931 {
932 public:
933     wxPliUserDataCD( SV* data )
934     {
935         dTHX;
936         m_data = data ? newSVsv( data ) : NULL;
937     }
938
939     ~wxPliUserDataCD()
940     {
941         dTHX;
942         SvREFCNT_dec( m_data );
943     }
944
945     SV* GetData() { return m_data; }
946 private:
947     SV* m_data;
948 };
949 typedef wxPliUserDataCD  Wx_UserDataCD;
950
951 #endif // __CPP_HELPERS_H_UDCD
952 #endif // defined( _WX_CLNTDATAH__ )
953
954 #if defined( _WX_TREEBASE_H_ ) || defined( _WX_TREECTRL_H_BASE_ )
955 #ifndef __CPP_HELPERS_H_TID
956 #define __CPP_HELPERS_H_TID
957
958 class wxPliTreeItemData:public wxTreeItemData
959 {
960 public:
961     wxPliTreeItemData( SV* data )
962         : m_data( NULL )
963     {
964         SetData( data );
965     }
966
967     ~wxPliTreeItemData()
968     {
969         SetData( NULL );
970     }
971
972     void SetData( SV* data )
973     {
974         dTHX;
975         if( m_data )
976             SvREFCNT_dec( m_data );
977         m_data = data ? newSVsv( data ) : NULL;
978     }
979 public:
980     SV* m_data;
981 };
982
983 #endif // __CPP_HELPERS_H_TID
984 #endif // defined( _WX_TREEBASE_H_ ) || defined( _WX_TREECTRL_H_BASE_ )
985
986 // Local variables:
987 // mode: c++
988 // End: