Skip to content
Snippets Groups Projects
FXRuby.h 29 KiB
Newer Older
/***********************************************************************
 * FXRuby -- the Ruby language bindings for the FOX GUI toolkit.
 * Copyright (c) 2001-2009 by Lyle Johnson. All Rights Reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * For further information please contact the author by e-mail
 * at "lyle@lylejohnson.name".
 ***********************************************************************/

/***********************************************************************
 * $Id: FXRuby.h 2463 2006-07-11 14:02:35Z lyle $
 ***********************************************************************/

#ifndef FXRUBY_H
#define FXRUBY_H

// RARRAY_LEN, RARRAY_PTR, RSTRING_LEN and RSTRING_PTR macros not defined before Ruby 1.8.6
#ifndef RARRAY_LEN
#define RARRAY_LEN(a) RARRAY((a))->len
#endif
#ifndef RARRAY_PTR
#define RARRAY_PTR(a) RARRAY((a))->ptr
#endif
#ifndef RSTRING_LEN
#define RSTRING_LEN(s) RSTRING((s))->len
#endif
#ifndef RSTRING_PTR
#define RSTRING_PTR(s) RSTRING((s))->ptr
#endif

// Opaque type declaration for SWIG runtime support
struct swig_type_info;

// SWIG runtime functions we need
extern "C" {
const char *     SWIG_Ruby_TypeName(const swig_type_info *ty);
swig_type_info * SWIG_Ruby_TypeQuery(const char *);
VALUE            SWIG_Ruby_NewPointerObj(void *ptr, swig_type_info *type, int own);
int              SWIG_Ruby_ConvertPtr(VALUE obj, void **ptr, swig_type_info *ty, int flags);
}

// Helper for overloaded show() functions
template <class TYPE>
VALUE showHelper(VALUE self, int argc, VALUE *argv, TYPE *p, swig_type_info *typeinfo) {
  TYPE *win;
  SWIG_Ruby_ConvertPtr(self,(void**)&win,typeinfo,1);
  if (argc == 0) {
    win->_show();
    }
  else if (argc == 1) {
    FXuint placement = NUM2UINT(argv[0]);
    win->FXTopWindow::show(placement);
    }
  else {
    rb_raise(rb_eArgError, "wrong # of arguments");
    }
  return Qnil;
  }
// Wrapper around SWIG_Ruby_NewPointerObj()
VALUE FXRbNewPointerObj(void *ptr, swig_type_info *typeinfo);
bool FXRbIsBorrowed(void* ptr);
bool FXRbSetInGC(const void* ptr, bool enabled);
bool FXRbIsInGC(const void* ptr);

// Wrapper around SWIG_TypeQuery()
swig_type_info *FXRbTypeQuery(const char *name);

// Wrapper around SWIG_ConvertPtr()
void* FXRbConvertPtr(VALUE obj,swig_type_info* typeinfo);

// Returns an FXInputHandle for this Ruby file object
FXInputHandle FXRbGetReadFileHandle(VALUE obj);
FXInputHandle FXRbGetWriteFileHandle(VALUE obj);

// Register mapping from Ruby objects to FOX objects
void FXRbRegisterRubyObj(VALUE rubyObj, const void* foxObj);

// Remove mapping for this FOX object and zero out any pointers
// to this (now dead) C++ object held by any Ruby object
void FXRbUnregisterRubyObj(const void* foxObj);

// Register an object that must be destroyed before FXApp is destroyed
void FXRbRegisterAppSensitiveObject(FXObject* obj);
void FXRbRegisterAppSensitiveObject(FXDC* dc);

// Unregister an object that must be destroyed before FXApp is destroyed
void FXRbUnregisterAppSensitiveObject(FXObject* obj);
void FXRbUnregisterAppSensitiveObject(FXDC* dc);

// Destroy all app-sensitive objects
void FXRbDestroyAppSensitiveObjects();

/**
 * Return the registered Ruby class instance associated with this
 * FOX object (if any). If searchBoth is false, only considers the
 * Ruby-owned objects; otherwise considers all outstanding references.
 */
VALUE FXRbGetRubyObj(const void *foxObj, bool searchBoth);

/**
 * Return the registered Ruby class instance associated with this
 * FOX object, or a new unregistered instance if not found.
 */
VALUE FXRbGetRubyObj(const void *foxObj, const char *type);
VALUE FXRbGetRubyObj(const void *foxObj, swig_type_info *type);

// Mark this object as used for the garbage collector
void FXRbGcMark(void *obj);

// Returns a Ruby array of floats
extern VALUE FXRbMakeArray(const FXfloat* values,FXint size);

// Returns a Ruby array of floats
extern VALUE FXRbMakeArray(const FXdouble* values,FXint size);

// Returns a Ruby array of integers
extern VALUE FXRbMakeArray(const FXint* values,FXint size);

// Returns a Ruby array of integers
extern VALUE FXRbMakeArray(const FXuint* values,FXint size);

// Returns a Ruby array of integers
extern VALUE FXRbMakeArray(const FXchar* dashpattern,FXuint dashlength);

// Returns a Ruby array of FXArcs
extern VALUE FXRbMakeArray(const FXArc* arcs,FXuint narcs);

// Returns a Ruby array of FXPoints
extern VALUE FXRbMakeArray(const FXPoint* points,FXuint npoints);

// Returns a Ruby array of FXRectangles
extern VALUE FXRbMakeArray(const FXRectangle* rectangles,FXuint nrectangles);

// Returns a Ruby array of FXSegments
extern VALUE FXRbMakeArray(const FXSegment* segments,FXuint nsegments);

// Returns a Ruby array of FXColor values
extern VALUE FXRbMakeColorArray(const FXColor* colors,FXint w,FXint h);

// Returns a number of FXColor elements in the argument
extern FXuint FXRbNumberOfFXColors(VALUE string_or_ary);

// Allocate a FXColor buffer and populate with data
extern FXColor *FXRbConvertToFXColors(VALUE string_or_ary);

extern void* FXRbGetExpectedData(VALUE recv,FXSelector key,VALUE data);

// Returns the name of the message handler function (or NULL)
ID FXRbLookupHandler(FXObject* recv,FXSelector key);

// Handle this message
long FXRbHandleMessage(FXObject* recv,ID func,FXObject* sender,FXSelector key,void* data);

// Convert a signal name string to its corresponding signal number
FXint FXRbSignalNameToNumber(const char* name);

// Fox module instance
extern VALUE mFox;

#ifdef HAVE_RUBY_ENCODING_H
// UTF-8 encoding index
extern int utf8_enc_idx;
#endif

// Convert from FOX datatypes to Ruby objects
inline VALUE to_ruby(const void* ptr){
  return Qnil; // FIXME: Used for some FXIconSource methods
  }

inline VALUE to_ruby(FXchar c){
  return INT2NUM(c);
  }

inline VALUE to_ruby(FXbool b){ // same as FXuchar
  return b ? Qtrue : Qfalse;
  }

inline VALUE to_ruby(FXshort s){
  return INT2NUM(s);
  }

inline VALUE to_ruby(FXushort u){
  return UINT2NUM(u);
  }

inline VALUE to_ruby(FXint i){
  return INT2NUM(i);
  }

inline VALUE to_ruby(FXuint u){
  return UINT2NUM(u);
  }

inline VALUE to_ruby(FXfloat f){
  return rb_float_new(f);
  }

inline VALUE to_ruby(FXdouble d){
  return rb_float_new(d);
  }

inline VALUE to_ruby(FXlong x){
  return LONG2NUM(x);
  }

inline VALUE to_ruby(FXulong x){
  return ULONG2NUM(x);
  }

#if !defined(__LP64__) && !defined(_LP64) && (_MIPS_SZLONG != 64) && (__WORDSIZE != 64)
inline VALUE to_ruby(unsigned long l){
  return ULONG2NUM(l);
  }
#endif

inline VALUE to_ruby(const FXString& s){
  VALUE str = rb_str_new(s.text(), s.length());
#ifdef HAVE_RUBY_ENCODING_H
  rb_enc_associate_index(str, utf8_enc_idx);
#endif
  return str;
  }

inline VALUE to_ruby(const FXchar* s){
  if(!s) return Qnil;
  VALUE str = rb_str_new2(s);
#ifdef HAVE_RUBY_ENCODING_H
  rb_enc_associate_index(str, utf8_enc_idx);
#endif
  return str;
  }

inline VALUE to_ruby(const FXchar* s, int length){
  VALUE str = rb_str_new(s, length);
#ifdef HAVE_RUBY_ENCODING_H
  rb_enc_associate_index(str, utf8_enc_idx);
#endif
  return str;
  }

extern VALUE to_ruby(const FXObject* obj);

inline VALUE to_ruby(const FXRangef& range){
  return FXRbNewPointerObj(static_cast<void*>(const_cast<FXRangef*>(&range)),FXRbTypeQuery("FXRangef *"));
  }

inline VALUE to_ruby(FXStream& store){
  return (VALUE) 0; // FIXME
  }

inline VALUE to_ruby(const FXPoint* point){
  return FXRbNewPointerObj(static_cast<void*>(const_cast<FXPoint*>(point)),FXRbTypeQuery("FXPoint *"));
  }
inline VALUE to_ruby(const FXSegment* segment){
  return FXRbNewPointerObj(static_cast<void*>(const_cast<FXSegment*>(segment)),FXRbTypeQuery("FXSegment *"));
  }

inline VALUE to_ruby(const FXRectangle* rect){
  return FXRbNewPointerObj(static_cast<void*>(const_cast<FXRectangle*>(rect)),FXRbTypeQuery("FXRectangle *"));
  }

inline VALUE to_ruby(const FXRectangle& rect){
  return FXRbNewPointerObj(static_cast<void*>(const_cast<FXRectangle*>(&rect)),FXRbTypeQuery("FXRectangle *"));
  }

inline VALUE to_ruby(const FXArc* arc){
  return FXRbNewPointerObj(static_cast<void*>(const_cast<FXArc*>(arc)),FXRbTypeQuery("FXArc *"));
  }

inline VALUE to_ruby(const FXRegion& region){
  return (VALUE) 0; // FIXME
  }

inline VALUE to_ruby(FXEvent* event){
  return FXRbGetRubyObj(reinterpret_cast<void*>(event),FXRbTypeQuery("FXEvent *"));
  }

inline VALUE to_ruby(FXTablePos* p){
  return SWIG_Ruby_NewPointerObj(reinterpret_cast<void*>(p),FXRbTypeQuery("FXTablePos *"),0);
  }

inline VALUE to_ruby(FXTextChange* p){
  return SWIG_Ruby_NewPointerObj(reinterpret_cast<void*>(p),FXRbTypeQuery("FXTextChange *"),0);
  }

inline VALUE to_ruby(FXTableRange* r){
  return SWIG_Ruby_NewPointerObj(reinterpret_cast<void*>(r),FXRbTypeQuery("FXTableRange *"),0);
  }

inline VALUE to_ruby(FXFontDesc* fontdesc){
  return FXRbNewPointerObj(reinterpret_cast<void*>(fontdesc),FXRbTypeQuery("FXFontDesc *"));
  }

inline VALUE to_ruby(const FXFontDesc& fontdesc){
  return FXRbNewPointerObj(reinterpret_cast<void*>(const_cast<FXFontDesc*>(&fontdesc)),FXRbTypeQuery("FXFontDesc *"));
  }

inline VALUE to_ruby(FXDC& dc){
  return FXRbGetRubyObj(reinterpret_cast<void*>(&dc),FXRbTypeQuery("FXDC *"));
  }

/**
 * Remember: FXID is typedef'd as an unsigned int on non-Windows platforms,
 * but as a void * on Win32.
 */
inline VALUE fxid_to_int(FXID id){
#ifndef WIN32
  return UINT2NUM(static_cast<unsigned int>(id));
#else
  return ULONG2NUM(reinterpret_cast<unsigned long>(id));
#endif
  }

/**
 * Remember: FXID is typedef'd as an unsigned int on non-Windows platforms,
 * but as a void * on Win32.
 */
inline FXID int_to_fxid(VALUE value){
#ifndef WIN32
  return static_cast<FXID>(NUM2UINT(value));
#else
  return reinterpret_cast<FXID>(NUM2ULONG(value));
#endif
  }

// Returns the beginning and ending values (inclusive) for a Range object
void FXRbRange2LoHi(VALUE range,FXint& lo,FXint& hi);
void FXRbRange2LoHi(VALUE range,FXdouble& lo,FXdouble& hi);

// Call function with "void" return value
void FXRbCallVoidMethod(FXObject* recv,ID func);

void FXRbCallVoidMethod(FXDC* recv,ID func);

/* One argument */
template<class TYPE>
void FXRbCallVoidMethod(FXObject* recv,ID func, TYPE& arg){
  VALUE obj=FXRbGetRubyObj(recv,false);
  FXASSERT(!NIL_P(obj));
  FXASSERT(!FXRbIsInGC(recv));
  rb_funcall(obj,func,1,to_ruby(arg));
  }

template<class TYPE>
void FXRbCallVoidMethod(FXDC* recv,ID func,TYPE arg){
  VALUE obj=FXRbGetRubyObj(recv,false);
  FXASSERT(!NIL_P(obj));
  rb_funcall(obj,func,1,to_ruby(arg));
  }
template<class TYPE>
void FXRbCallVoidMethod(const FXObject* recv, ID func, TYPE& arg){
  VALUE obj=FXRbGetRubyObj(recv,false);
  FXASSERT(!NIL_P(obj));
  FXASSERT(!FXRbIsInGC(recv));
371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874
  rb_funcall(obj,func,1,to_ruby(arg));
  }

/* Two arguments */
template<class TYPE1, class TYPE2>
void FXRbCallVoidMethod(FXObject* recv,ID func,TYPE1 arg1,TYPE2 arg2){
  VALUE obj=FXRbGetRubyObj(recv,false);
  FXASSERT(!NIL_P(obj));
  rb_funcall(obj,func,2,to_ruby(arg1),to_ruby(arg2));
  }

template<class TYPE1, class TYPE2>
void FXRbCallVoidMethod(FXDC* recv,ID func,TYPE1 arg1,TYPE2 arg2){
  VALUE obj=FXRbGetRubyObj(recv,false);
  FXASSERT(!NIL_P(obj));
  rb_funcall(obj,func,2,to_ruby(arg1),to_ruby(arg2));
  }

FXTreeItem* FXRbCallTreeItemMethod(const FXTreeList* recv,ID func,FXint x,FXint y);
FXFoldingItem* FXRbCallFoldingItemMethod(const FXFoldingList* recv,ID func,FXint x,FXint y);

/* Three arguments */
template<class TYPE1, class TYPE2, class TYPE3>
void FXRbCallVoidMethod(FXObject* recv,ID func,TYPE1 arg1,TYPE2 arg2,TYPE3 arg3){
  VALUE obj=FXRbGetRubyObj(recv,false);
  FXASSERT(!NIL_P(obj));
  rb_funcall(obj,func,3,to_ruby(arg1),to_ruby(arg2),to_ruby(arg3));
  }

template<class TYPE1, class TYPE2, class TYPE3>
void FXRbCallVoidMethod(FXDC* recv,ID func,TYPE1 arg1,TYPE2 arg2,TYPE3 arg3){
  VALUE obj=FXRbGetRubyObj(recv,false);
  FXASSERT(!NIL_P(obj));
  rb_funcall(obj,func,3,to_ruby(arg1),to_ruby(arg2),to_ruby(arg3));
  }

/* Four arguments */
template<class TYPE1, class TYPE2, class TYPE3, class TYPE4>
void FXRbCallVoidMethod(FXObject* recv,ID func, TYPE1 arg1, TYPE2 arg2, TYPE3 arg3, TYPE4 arg4){
  VALUE obj=FXRbGetRubyObj(recv,false);
  FXASSERT(!NIL_P(obj));
  rb_funcall(obj,func,4,to_ruby(arg1),to_ruby(arg2),to_ruby(arg3),to_ruby(arg4));
  }

template<class TYPE1, class TYPE2, class TYPE3, class TYPE4>
void FXRbCallVoidMethod(FXDC* recv,ID func,TYPE1 arg1,TYPE2 arg2,TYPE3 arg3,TYPE4 arg4){
  VALUE obj=FXRbGetRubyObj(recv,false);
  FXASSERT(!NIL_P(obj));
  rb_funcall(obj,func,4,to_ruby(arg1),to_ruby(arg2),to_ruby(arg3),to_ruby(arg4));
  }

/* Five arguments */
template<class TYPE1, class TYPE2, class TYPE3, class TYPE4, class TYPE5>
void FXRbCallVoidMethod(FXObject* recv,ID func,TYPE1& arg1,TYPE2 arg2,TYPE3 arg3,TYPE4 arg4,TYPE5 arg5){
  VALUE obj=FXRbGetRubyObj(recv,false);
  FXASSERT(!NIL_P(obj));
  rb_funcall(obj,func,5,to_ruby(arg1),to_ruby(arg2),to_ruby(arg3),to_ruby(arg4),to_ruby(arg5));
  }

template<class TYPE1, class TYPE2, class TYPE3, class TYPE4, class TYPE5>
void FXRbCallVoidMethod(FXDC* recv, ID func, TYPE1 arg1, TYPE2 arg2, TYPE3 arg3, TYPE4 arg4, TYPE5 arg5){
  VALUE obj=FXRbGetRubyObj(recv,false);
  FXASSERT(!NIL_P(obj));
  rb_funcall(obj,func,5,to_ruby(arg1),to_ruby(arg2),to_ruby(arg3),to_ruby(arg4),to_ruby(arg5));
  }

/* Six arguments */
template<class TYPE1, class TYPE2, class TYPE3, class TYPE4, class TYPE5, class TYPE6>
void FXRbCallVoidMethod(const FXObject* recv, ID func, TYPE1 arg1, TYPE2& arg2, TYPE3 arg3, TYPE4 arg4, TYPE5 arg5, TYPE6 arg6){
  VALUE obj=FXRbGetRubyObj(recv,false);
  FXASSERT(!NIL_P(obj));
  rb_funcall(obj,func,6,to_ruby(arg1),to_ruby(arg2),to_ruby(arg3),to_ruby(arg4),to_ruby(arg5),to_ruby(arg6));
  }

template<class TYPE1, class TYPE2, class TYPE3, class TYPE4, class TYPE5, class TYPE6>
void FXRbCallVoidMethod(FXDC* recv, ID func, TYPE1 arg1, TYPE2 arg2, TYPE3 arg3, TYPE4 arg4, TYPE5 arg5, TYPE6 arg6){
  VALUE obj=FXRbGetRubyObj(recv,false);
  FXASSERT(!NIL_P(obj));
  rb_funcall(obj,func,6,to_ruby(arg1),to_ruby(arg2),to_ruby(arg3),to_ruby(arg4),to_ruby(arg5),to_ruby(arg6));
  }

/* Seven arguments */
template<class TYPE1, class TYPE2, class TYPE3, class TYPE4, class TYPE5, class TYPE6, class TYPE7>
void FXRbCallVoidMethod(FXDC* recv, ID func, TYPE1 arg1, TYPE2 arg2, TYPE3 arg3, TYPE4 arg4, TYPE5 arg5, TYPE6 arg6, TYPE7 arg7){
  VALUE obj=FXRbGetRubyObj(recv,false);
  FXASSERT(!NIL_P(obj));
  rb_funcall(obj,func,7,to_ruby(arg1),to_ruby(arg2),to_ruby(arg3),to_ruby(arg4),to_ruby(arg5),to_ruby(arg6),to_ruby(arg7));
  }

/* Nine arguments */
template<class TYPE1, class TYPE2, class TYPE3, class TYPE4, class TYPE5, class TYPE6, class TYPE7, class TYPE8, class TYPE9>
void FXRbCallVoidMethod(FXDC* recv, ID func, TYPE1 arg1, TYPE2 arg2, TYPE3 arg3, TYPE4 arg4, TYPE5 arg5, TYPE6 arg6, TYPE7 arg7, TYPE8 arg8, TYPE9 arg9){
  VALUE obj=FXRbGetRubyObj(recv,false);
  FXASSERT(!NIL_P(obj));
  rb_funcall(obj,func,9,to_ruby(arg1),to_ruby(arg2),to_ruby(arg3),to_ruby(arg4),to_ruby(arg5),to_ruby(arg6),to_ruby(arg7), to_ruby(arg8), to_ruby(arg9));
  }

/* Eleven arguments (!) */
template<class TYPE1,class TYPE2,class TYPE3,class TYPE4,class TYPE5,class TYPE6,class TYPE7,class TYPE8,class TYPE9,class TYPE10,class TYPE11>
void FXRbCallVoidMethod(FXObject* recv,ID func,TYPE1& arg1,TYPE2 arg2,TYPE3 arg3,TYPE4 arg4,TYPE5 arg5,TYPE6 arg6,TYPE7 arg7,TYPE8 arg8,TYPE9 arg9,TYPE10 arg10,TYPE11 arg11){
  VALUE obj=FXRbGetRubyObj(recv,false);
  FXASSERT(!NIL_P(obj));
  rb_funcall(obj,func,11,to_ruby(arg1),to_ruby(arg2),to_ruby(arg3),to_ruby(arg4),to_ruby(arg5),to_ruby(arg6),to_ruby(arg7),to_ruby(arg8),to_ruby(arg9),to_ruby(arg10),to_ruby(arg11));
  }

// Call function with "FXbool" return value
inline bool FXRbCallBoolMethod(FXStream* recv,ID func){
  VALUE v=rb_funcall(FXRbGetRubyObj(recv,false),func,0,NULL);
  return (v==Qtrue);
  }

template<class TYPE1>
bool FXRbCallBoolMethod(FXStream* recv,ID func,TYPE1 arg){
  VALUE v=rb_funcall(FXRbGetRubyObj(recv,false),func,1,to_ruby(arg));
  return (v==Qtrue);
  }

template<class TYPE1,class TYPE2>
bool FXRbCallBoolMethod(FXStream* recv,ID func,TYPE1 arg1,TYPE2 arg2){
  VALUE v=rb_funcall(FXRbGetRubyObj(recv,false),func,2,to_ruby(arg1),to_ruby(arg2));
  return (v==Qtrue);
  }

bool FXRbCallBoolMethod(const FXObject* recv,ID func);

template<class TYPE>
bool FXRbCallBoolMethod(FXObject* recv, ID func, TYPE& arg){
  VALUE obj=FXRbGetRubyObj(recv,false);
  FXASSERT(!NIL_P(obj));
  VALUE v=rb_funcall(obj,func,1,to_ruby(arg));
  return (v==Qtrue);
  }

template<class TYPE>
bool FXRbCallBoolMethod(const FXObject* recv,ID func,TYPE& arg){
  VALUE v=rb_funcall(FXRbGetRubyObj(recv,false),func,1,to_ruby(arg));
  return (v==Qtrue);
  }

template<class TYPE1, class TYPE2>
bool FXRbCallBoolMethod(const FXObject* recv, ID func, TYPE1 arg1, TYPE2 arg2){
  VALUE obj=FXRbGetRubyObj(recv,false);
  FXASSERT(!NIL_P(obj));
  VALUE v=rb_funcall(obj,func,2,to_ruby(arg1),to_ruby(arg2));
  return (v==Qtrue);
  }

template<class TYPE1, class TYPE2, class TYPE3>
bool FXRbCallBoolMethod(const FXObject* recv, ID func, TYPE1 arg1, TYPE2 arg2, TYPE3 arg3){
  VALUE obj=FXRbGetRubyObj(recv,false);
  FXASSERT(!NIL_P(obj));
  VALUE v=rb_funcall(obj,func,3,to_ruby(arg1),to_ruby(arg2),to_ruby(arg3));
  return (v==Qtrue);
  }

template<class TYPE1, class TYPE2, class TYPE3, class TYPE4, class TYPE5>
bool FXRbCallBoolMethod(const FXObject* recv, ID func, TYPE1 arg1, TYPE2 arg2, TYPE3 arg3, TYPE4 arg4, TYPE5 arg5){
  VALUE obj=FXRbGetRubyObj(recv,false);
  FXASSERT(!NIL_P(obj));
  VALUE v=rb_funcall(obj,func,5,to_ruby(arg1),to_ruby(arg2),to_ruby(arg3),to_ruby(arg4),to_ruby(arg5));
  return (v==Qtrue);
  }

// Call function with "FXint" return value
FXint FXRbCallIntMethod(const FXObject* recv,ID func);

template<class TYPE>
FXint FXRbCallIntMethod(FXObject* recv, ID func, TYPE arg){
  VALUE obj=FXRbGetRubyObj(recv,false);
  FXASSERT(!NIL_P(obj));
  VALUE v=rb_funcall(obj,func,1,to_ruby(arg));
  return static_cast<FXint>(NUM2INT(v));
  }

template<class TYPE>
FXint FXRbCallIntMethod(const FXObject* recv, ID func, TYPE arg){
  VALUE obj=FXRbGetRubyObj(recv,false);
  FXASSERT(!NIL_P(obj));
  VALUE v=rb_funcall(obj,func,1,to_ruby(arg));
  return static_cast<FXint>(NUM2INT(v));
  }

template<class TYPE1, class TYPE2>
FXint FXRbCallIntMethod(const FXObject* recv, ID func, TYPE1 arg1, TYPE2 arg2){
  VALUE obj=FXRbGetRubyObj(recv,false);
  FXASSERT(!NIL_P(obj));
  VALUE result=rb_funcall(obj,func,2,to_ruby(arg1),to_ruby(arg2));
  return static_cast<FXint>(NUM2INT(result));
  }

template<class TYPE1, class TYPE2, class TYPE3, class TYPE4, class TYPE5>
FXint FXRbCallIntMethod(const FXObject* recv, ID func, TYPE1 arg1, TYPE2 arg2, TYPE3 arg3, TYPE4 arg4, TYPE5 arg5){
  VALUE obj=FXRbGetRubyObj(recv,false);
  FXASSERT(!NIL_P(obj));
  VALUE result=rb_funcall(obj,func,5,to_ruby(arg1),to_ruby(arg2),to_ruby(arg3),to_ruby(arg4),to_ruby(arg5));
  return static_cast<FXint>(NUM2INT(result));
  }

// Call function with "long" return value
template<class TYPE1, class TYPE2, class TYPE3>
long FXRbCallLongMethod(FXObject* recv, ID func, TYPE1 arg1, TYPE2 arg2, TYPE3 arg3){
  VALUE obj=FXRbGetRubyObj(recv,false);
  FXASSERT(!NIL_P(obj));
  VALUE v=rb_funcall(obj,func,3,to_ruby(arg1),to_ruby(arg2),to_ruby(arg3));
  return static_cast<long>(NUM2LONG(v));
  }

// Call functions with "FXuint" return value
template<class TYPE>
FXuint FXRbCallUIntMethod(FXObject* recv, ID func, TYPE arg){
  VALUE obj=FXRbGetRubyObj(recv,false);
  FXASSERT(!NIL_P(obj));
  VALUE v=rb_funcall(obj,func,1,to_ruby(arg));
  return static_cast<FXuint>(NUM2UINT(v));
  }

// Call functions with FXString return value
FXString FXRbCallStringMethod(const FXObject* recv, ID func);

// Call functions with const FXchar* return value
const FXchar* FXRbCallCStringMethod(const FXObject* recv, ID func, const FXchar*, const FXchar*);
const FXchar* FXRbCallCStringMethod(const FXObject* recv, ID func, const FXchar*, const FXchar*, const FXchar*);

// Call functions with "FXGLObject*" return value
FXGLObject* FXRbCallGLObjectMethod(FXGLObject* recv,ID func);
FXGLObject* FXRbCallGLObjectMethod(FXGLObject* recv,ID func,FXuint* path,FXint n);
FXGLObject* FXRbCallGLObjectMethod(FXGLViewer* recv,ID func,FXint x,FXint y);

// Call functions with "FXGLObject**" return value
FXGLObject** FXRbCallGLObjectArrayMethod(FXGLViewer* recv,ID func,FXint x,FXint y,FXint w,FXint h);

// Call functions with "FXTreeItem*" return value
FXTableItem* FXRbCallTableItemMethod(FXTable* recv,ID func,const FXString& text,FXIcon* icon,void* ptr);

// Call functions with "FXTreeItem*" return value
FXTableItem* FXRbCallTableItemMethod(FXTable* recv,ID func,FXint,FXint,FXbool);

// Call functions with "FXFileAssoc*" return value
FXFileAssoc* FXRbCallFileAssocMethod(const FXFileDict* recv,ID func,const FXchar* pathname);

// Call functions with "FXIcon*" return value
FXIcon* FXRbCallIconMethod(const FXTableItem* recv,ID func);

template<class TYPE1, class TYPE2>
FXIcon* FXRbCallIconMethod(const FXIconSource *recv,ID func,TYPE1& arg1,const TYPE2& arg2){
  VALUE obj=FXRbGetRubyObj(recv,false);
  FXASSERT(!NIL_P(obj));
  VALUE result=rb_funcall(obj,func,2,to_ruby(arg1),to_ruby(arg2));
  return NIL_P(result) ? 0 : reinterpret_cast<FXIcon*>(DATA_PTR(result));
  }

template<class TYPE1, class TYPE2, class TYPE3, class TYPE4>
FXIcon* FXRbCallIconMethod(const FXIconSource *recv,ID func,TYPE1& arg1,TYPE2 arg2,TYPE3 arg3,const TYPE4& arg4){
  VALUE obj=FXRbGetRubyObj(recv,false);
  FXASSERT(!NIL_P(obj));
  VALUE result=rb_funcall(obj,func,4,to_ruby(arg1),to_ruby(arg2),to_ruby(arg3),to_ruby(arg4));
  return NIL_P(result) ? 0 : reinterpret_cast<FXIcon*>(DATA_PTR(result));
  }

// Call functions with FXImage* return value
template<class TYPE1, class TYPE2>
FXImage* FXRbCallImageMethod(const FXIconSource *recv,ID func,TYPE1& arg1,const TYPE2& arg2){
  VALUE obj=FXRbGetRubyObj(recv,false);
  FXASSERT(!NIL_P(obj));
  VALUE result=rb_funcall(obj,func,2,to_ruby(arg1),to_ruby(arg2));
  return NIL_P(result) ? 0 : reinterpret_cast<FXImage*>(DATA_PTR(result));
  }

template<class TYPE1, class TYPE2, class TYPE3, class TYPE4>
FXImage* FXRbCallImageMethod(const FXIconSource *recv,ID func,TYPE1& arg1,TYPE2 arg2,TYPE3 arg3,const TYPE4& arg4){
  VALUE obj=FXRbGetRubyObj(recv,false);
  FXASSERT(!NIL_P(obj));
  VALUE result=rb_funcall(obj,func,4,to_ruby(arg1),to_ruby(arg2),to_ruby(arg3),to_ruby(arg4));
  return NIL_P(result) ? 0 : reinterpret_cast<FXImage*>(DATA_PTR(result));
  }

// Call functions with "FXWindow*" return value
FXWindow* FXRbCallWindowMethod(const FXTableItem* recv,ID func,FXTable* table);

// Call functions with "FXColor" return value
template<class TYPE1, class TYPE2>
FXColor FXRbCallColorMethod(FXDC* recv, ID func, TYPE1 arg1, TYPE2 arg2){
  VALUE obj=FXRbGetRubyObj(recv,false);
  FXASSERT(!NIL_P(obj));
  VALUE v=rb_funcall(obj,func,2,to_ruby(arg1),to_ruby(arg2));
  return static_cast<FXColor>(NUM2UINT(v));
  }

// Call functions with "FXRangef" return value
FXRangef FXRbCallRangeMethod(FXObject* recv,ID func);

// Call functions with FXwchar return value
FXwchar FXRbCallWCharMethod(const FXObject* recv,ID func);

/**
 * Macro to set up class implementation.
 * This is a modified version of the standard FOX macro FXIMPLEMENT();
 * this version's implementation of the virtual handle() function
 * first checks the Ruby class instance's message map to see if it
 * can handle the incoming message. If not, the regular C++ message
 * mapping takes over as in standard FOX applications.
 */

#define FXRbIMPLEMENT(classname,baseclassname,mapping,nmappings) \
  FXObject* classname::manufacture(){return new classname;} \
  const FX::FXMetaClass classname::metaClass(#classname,classname::manufacture,&baseclassname::metaClass,mapping,nmappings,sizeof(classname::FXMapEntry)); \
  long classname::handle(FXObject* sender,FXSelector key,void* ptr){ \
    ID func=FXRbLookupHandler(this,key); \
    if(func!=0){ \
      return FXRbHandleMessage(this,func,sender,key,ptr); \
      } \
    else{ \
      const FXMapEntry* me=reinterpret_cast<const FXMapEntry*>(metaClass.search(key)); \
      return me ? (this->* me->func)(sender,key,ptr) : baseclassname::handle(sender,key,ptr); \
      } \
    }


// FXRuby classes
#include "FXRbStream.h"
#include "FXRbObject.h"
#include "FXRbDelegator.h"
#include "FXRbDict.h"
#include "FXRbStringDict.h"
#include "FXRbAccelTable.h"
#include "FXRbRecentFiles.h"
#include "FXRbApp.h"
#include "FXRbId.h"
#include "FXRbVisual.h"
#include "FXRbFont.h"
#include "FXRbCursor.h"
#include "FXRbCURCursor.h"
#include "FXRbGIFCursor.h"
#include "FXRbDrawable.h"
#include "FXRbBitmap.h"
#include "FXMemoryBuffer.h"
#include "FXRbImage.h"
#include "FXRbBMPImage.h"
#include "FXRbGIFImage.h"
#include "FXRbICOImage.h"
#include "FXRbJPGImage.h"
#include "FXRbPCXImage.h"
#include "FXRbPNGImage.h"
#include "FXRbPPMImage.h"
#include "FXRbRGBImage.h"
#include "FXRbTGAImage.h"
#include "FXRbTIFImage.h"
#include "FXRbXBMImage.h"
#include "FXRbXPMImage.h"
#include "FXRbIcon.h"
#include "FXRbBMPIcon.h"
#include "FXRbGIFIcon.h"
#include "FXRbICOIcon.h"
#include "FXRbJPGIcon.h"
#include "FXRbPCXIcon.h"
#include "FXRbPNGIcon.h"
#include "FXRbPPMIcon.h"
#include "FXRbRGBIcon.h"
#include "FXRbTGAIcon.h"
#include "FXRbTIFIcon.h"
#include "FXRbXBMIcon.h"
#include "FXRbXPMIcon.h"
#include "FXRbDC.h"
#include "FXRbDCWindow.h"
#include "FXRbDCPrint.h"
#include "FXRbFileDict.h"
#include "FXRbWindow.h"
#include "FXRbFrame.h"
#include "FXRbKnob.h"
#include "FXRb7Segment.h"
#include "FXRbDockHandler.h"
#include "FXRbDockTitle.h"
#include "FXRbSeparator.h"
#include "FXRbLabel.h"
#include "FXRbDial.h"
#include "FXRbColorBar.h"
#include "FXRbColorRing.h"
#include "FXRbColorWell.h"
#include "FXRbColorWheel.h"
#include "FXRbTextField.h"
#include "FXRbButton.h"
#include "FXRbPicker.h"
#include "FXRbToggleButton.h"
#include "FXRbTriStateButton.h"
#include "FXRbCheckButton.h"
#include "FXRbRadioButton.h"
#include "FXRbArrowButton.h"
#include "FXRbMenuButton.h"
#include "FXRbComposite.h"
#include "FXRbPacker.h"
#include "FXRbDockBar.h"
#include "FXRbDockSite.h"
#include "FXRbSpring.h"
#include "FXRbHorizontalFrame.h"
#include "FXRbVerticalFrame.h"
#include "FXRbMatrix.h"
#include "FXRbSpinner.h"
#include "FXRbRealSpinner.h"
#include "FXRbRootWindow.h"
#include "FXRbCanvas.h"
#include "FXRbGroupBox.h"
#include "FXRbShell.h"
#include "FXRbToolTip.h"
#include "FXRbPopup.h"
#include "FXRbTopWindow.h"
#include "FXRbSplashWindow.h"
#include "FXRbDialogBox.h"
#include "FXRbMainWindow.h"
#include "FXRbMenuPane.h"
#include "FXRbScrollPane.h"
#include "FXRbMenuCaption.h"
#include "FXRbMenuSeparator.h"
#include "FXRbMenuTitle.h"
#include "FXRbMenuCascade.h"
#include "FXRbMenuCommand.h"
#include "FXRbMenuCheck.h"
#include "FXRbMenuRadio.h"
#include "FXRbToolBar.h"
#include "FXRbMenuBar.h"
#include "FXRbOptionMenu.h"
#include "FXRbSwitcher.h"
#include "FXRbTabBar.h"
#include "FXRbTabBook.h"
#include "FXRbTabItem.h"
#include "FXRbScrollBar.h"
#include "FXRbScrollArea.h"
#include "FXRbScrollWindow.h"
#include "FXRbList.h"
#include "FXRbColorList.h"
#include "FXRbComboBox.h"
#include "FXRbListBox.h"
#include "FXRbFoldingList.h"
#include "FXRbTreeList.h"
#include "FXRbTreeListBox.h"
// #include "FXRbBitmapView.h"
#include "FXRbImageView.h"
#include "FXRbTable.h"
#include "FXRbDragCorner.h"
#include "FXRbStatusBar.h"
#include "FXRbStatusLine.h"
#include "FXRbMessageBox.h"
#include "FXRbDirList.h"
#include "FXRbRealSlider.h"
#include "FXRbSlider.h"
#include "FXRbSplitter.h"
#include "FXRb4Splitter.h"
#include "FXRbHeader.h"
#include "FXRbShutter.h"
#include "FXRbIconList.h"
#include "FXRbIconSource.h"
#include "FXRbFileList.h"
#include "FXRbDirBox.h"
#include "FXRbDriveBox.h"
#include "FXRbDirSelector.h"
#include "FXRbDirDialog.h"
#include "FXRbFileSelector.h"
#include "FXRbFileDialog.h"
#include "FXRbColorSelector.h"
#include "FXRbColorDialog.h"
#include "FXRbFontSelector.h"
#include "FXRbFontDialog.h"
#include "FXRbText.h"
#include "FXRbDataTarget.h"
#include "FXRbProgressBar.h"
#include "FXRbSearchDialog.h"
#include "FXRbReplaceDialog.h"
#include "FXRbInputDialog.h"
#include "FXRbProgressDialog.h"
#include "FXRbChoiceBox.h"
#include "FXRbMDIButton.h"
#include "FXRbMDIClient.h"
#include "FXRbMDIChild.h"
#include "FXRbDocument.h"
#include "FXRbToolBarGrip.h"
#include "FXRbToolBarShell.h"
#include "FXRbToolBarTab.h"
#include "FXRbPrintDialog.h"
#include "FXRbDebugTarget.h"
#include "FXRbGradientBar.h"
#include "FXRbBitmapFrame.h"
#include "FXRbImageFrame.h"
#include "FXRbRuler.h"
#include "FXRbRulerView.h"
#include "FXRbWizard.h"
#ifdef WITH_FXSCINTILLA
#include "FXRbScintilla.h"
#endif
#include "FXRbSettings.h"
#include "FXRbRegistry.h"
#include "FXRbTranslator.h"

// OpenGL support
#include "FXRbGLVisual.h"
#include "FXRbGLContext.h"
#include "FXRbGLCanvas.h"
#include "FXRbGLViewer.h"
#include "FXRbGLObject.h"
#include "FXRbGLShape.h"

// Inlined implementations of stubs
#include "inlinestubs.h"

#endif