summaryrefslogtreecommitdiff
path: root/scipy/weave/wx_spec.py
blob: 5e75877d298d6bc99278e383d1c604a3cfaf9146 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
import common_info
from c_spec import common_base_converter
import sys,os

# these may need user configuration.
if sys.platform == "win32":
    wx_base = r'c:\third\wxpython-2.4.0.7'
else:
    # probably should do some more discovery here.
    wx_base = '/usr/lib/wxPython'

def get_wxconfig(flag):
    wxconfig = os.path.join(wx_base,'bin','wx-config')
    import commands
    res,settings = commands.getstatusoutput(wxconfig + ' --' + flag)
    if res:
        msg = wxconfig + ' failed. Impossible to learn wxPython settings'
        raise RuntimeError, msg
    return settings.split()

wx_to_c_template = \
"""
class %(type_name)s_handler
{
public:    
    %(c_type)s convert_to_%(type_name)s(PyObject* py_obj, const char* name)
    {
        %(c_type)s wx_ptr;        
        // work on this error reporting...
        if (SWIG_GetPtrObj(py_obj,(void **) &wx_ptr,"_%(type_name)s_p"))
            handle_conversion_error(py_obj,"%(type_name)s", name);
        %(inc_ref_count)s
        return wx_ptr;
    }
    
    %(c_type)s py_to_%(type_name)s(PyObject* py_obj,const char* name)
    {
        %(c_type)s wx_ptr;        
        // work on this error reporting...
        if (SWIG_GetPtrObj(py_obj,(void **) &wx_ptr,"_%(type_name)s_p"))
            handle_bad_type(py_obj,"%(type_name)s", name);
        %(inc_ref_count)s
        return wx_ptr;
    }    
};

%(type_name)s_handler x__%(type_name)s_handler = %(type_name)s_handler();
#define convert_to_%(type_name)s(py_obj,name) \\
        x__%(type_name)s_handler.convert_to_%(type_name)s(py_obj,name)
#define py_to_%(type_name)s(py_obj,name) \\
        x__%(type_name)s_handler.py_to_%(type_name)s(py_obj,name)

"""

class wx_converter(common_base_converter):
    def __init__(self,class_name="undefined"):
        self.class_name = class_name
        common_base_converter.__init__(self)

    def init_info(self):
        common_base_converter.init_info(self)
        # These are generated on the fly instead of defined at 
        # the class level.
        self.type_name = self.class_name
        self.c_type = self.class_name + "*"
        self.return_type = self.class_name + "*"
        self.to_c_return = None # not used
        self.check_func = None # not used
        self.headers.append('"wx/wx.h"')
        if sys.platform == "win32":        
            # These will be used in many cases
            self.headers.append('<windows.h>')        
            
            # These are needed for linking.
            self.libraries.extend(['kernel32','user32','gdi32','comdlg32',
                                   'winspool', 'winmm', 'shell32', 
                                   'oldnames', 'comctl32', 'ctl3d32',
                                   'odbc32', 'ole32', 'oleaut32', 
                                   'uuid', 'rpcrt4', 'advapi32', 'wsock32'])
                                   
            # not sure which of these macros are needed.
            self.define_macros.append(('WIN32', '1'))
            self.define_macros.append(('__WIN32__', '1'))
            self.define_macros.append(('_WINDOWS', '1'))
            self.define_macros.append(('STRICT', '1'))
            # I think this will only work on NT/2000/XP set
            # set to 0x0400 for earlier versions.
            # Hmmm.  setting this breaks stuff
            #self.define_macros.append(('WINVER', '0x0350'))

            self.library_dirs.append(os.path.join(wx_base,'lib'))
            #self.include_dirs.append(os.path.join(wx_base,'include'))            
            self.include_dirs.append(wx_base)            
            self.include_dirs.append(os.path.join(wx_base,'include'))            
            self.include_dirs.append(os.path.join(wx_base,'include','msw'))            
            # how do I discover unicode or not unicode??            
            # non-unicode            
            self.libraries.append('wxmsw24h')
            self.include_dirs.append(os.path.join(wx_base,'lib'))
            
            # unicode
            #self.libraries.append('wxmswuh')
            #self.include_dirs.append(os.path.join(wx_base,'lib','mswdlluh'))
            #self.define_macros.append(('UNICODE', '1'))
        else:
            # make sure the gtk files are available 
            # ?? Do I need to link to them?
            self.headers.append('"gdk/gdk.h"')
            # !! This shouldn't be hard coded.
            self.include_dirs.append("/usr/include/gtk-1.2")
            self.include_dirs.append("/usr/include/glib-1.2")
            self.include_dirs.append("/usr/lib/glib/include")
            cxxflags = get_wxconfig('cxxflags')
            libflags = get_wxconfig('libs') + get_wxconfig('gl-libs')
            
            #older versions of wx do not support the ldflags.
            try:
                ldflags = get_wxconfig('ldflags')
            except RuntimeError:
                ldflags = []
                    
            self.extra_compile_args.extend(cxxflags)
            self.extra_link_args.extend(libflags)
            self.extra_link_args.extend(ldflags)            
        self.support_code.append(common_info.swig_support_code)
    
    def type_match(self,value):
        is_match = 0
        try:
            wx_class = value.this.split('_')[-2]
            if wx_class[:2] == 'wx':
                is_match = 1
        except AttributeError:
            pass
        return is_match

    def generate_build_info(self):
        if self.class_name != "undefined":
            res = common_base_converter.generate_build_info(self)
        else:
            # if there isn't a class_name, we don't want the
            # we don't want the support_code to be included
            import base_info
            res = base_info.base_info()
        return res
        
    def py_to_c_code(self):
        return wx_to_c_template % self.template_vars()

    #def c_to_py_code(self):
    #    return simple_c_to_py_template % self.template_vars()
                    
    def type_spec(self,name,value):
        # factory
        class_name = value.this.split('_')[-2]
        new_spec = self.__class__(class_name)
        new_spec.name = name        
        return new_spec

    def __cmp__(self,other):
        #only works for equal
        res = -1
        try:
            res = cmp(self.name,other.name) or \
                  cmp(self.__class__, other.__class__) or \
                  cmp(self.class_name, other.class_name) or \
                  cmp(self.type_name,other.type_name)
        except:
            pass
        return res