1 /*
2  * %CopyrightBegin%
3  *
4  * Copyright Ericsson AB 2008-2016. All Rights Reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * %CopyrightEnd%
19  */
20 
21 #include <wx/wx.h>
22 #include "wxe_impl.h"
23 #include "wxe_return.h"
24 #include "wxe_events.h"
25 #include "wxe_gl.h"
26 #include "gen/wxe_macros.h"
27 #include "gen/wxe_derived_dest.h"
28 
29 
30 /* ****************************************************************************
31  * CallbackData *
32  * ****************************************************************************/
33 
wxeEvtListener(ErlNifPid caller,int req,ERL_NIF_TERM req_type,int funcb,int skip_ev,wxeErlTerm * userData,wxe_me_ref * mr)34 wxeEvtListener::wxeEvtListener(ErlNifPid caller, int req, ERL_NIF_TERM req_type,
35 			       int funcb, int skip_ev, wxeErlTerm * userData,
36 			       wxe_me_ref *mr)
37   : wxEvtHandler()
38 {
39   me_ref=mr;
40   listener = caller;
41   obj = req;
42   fun_id = funcb;
43   class_name = req_type;
44   skip = skip_ev;
45   user_data = userData;
46 }
47 
~wxeEvtListener()48 wxeEvtListener::~wxeEvtListener() {
49   // enif_fprintf(stderr, "CBD Deleteing %p %T\r\n", this, class_name); fflush(stderr);
50   if(user_data) {
51     delete user_data;
52   }
53   ptrMap::iterator it;
54   it = ((WxeApp *)wxTheApp)->ptr2ref.find(this);
55   wxeMemEnv *memenv = (wxeMemEnv *) me_ref->memenv;
56   if(it != ((WxeApp *)wxTheApp)->ptr2ref.end() && memenv) {
57     wxeRefData *refd = it->second;
58     wxeReturn rt = wxeReturn(memenv, memenv->owner, false);
59     rt.send(enif_make_tuple4(rt.env,
60                              rt.make_atom("wx_delete_cb"),
61                              rt.make_int(fun_id),
62                              rt.make_ref(refd->ref, "wxeEvtListener"),
63                              rt.make_ref(obj, class_name)));
64   }
65   ((WxeApp *)wxTheApp)->clearPtr(this);
66 }
67 
forward(wxEvent & event)68 void wxeEvtListener::forward(wxEvent& event)
69 {
70   if(me_ref->memenv)
71     sendevent(&event, (wxeMemEnv *)me_ref->memenv);
72 }
73 
74 /* *****************************************************************/
75 /* Printing special */
76 
~EwxPrintout()77 EwxPrintout::~EwxPrintout() {
78   clear_cb(me_ref, onPrintPage);
79   clear_cb(me_ref, onPreparePrinting);
80   clear_cb(me_ref, onBeginPrinting);
81   clear_cb(me_ref, onEndPrinting);
82   clear_cb(me_ref, onBeginDocument);
83   clear_cb(me_ref, onEndDocument);
84   clear_cb(me_ref, hasPage);
85   clear_cb(me_ref, getPageInfo);
86 
87   ((WxeApp *)wxTheApp)->clearPtr(this);
88 }
89 
OnBeginDocument(int startPage,int endPage)90 bool EwxPrintout::OnBeginDocument(int startPage, int endPage)
91 {
92   wxeMemEnv *memenv = (wxeMemEnv *) me_ref->memenv;
93   if(onBeginDocument && memenv) {
94     wxeReturn rt = wxeReturn(memenv, memenv->owner, false);
95     ERL_NIF_TERM args = enif_make_list(rt.env, 2,
96                                        rt.make_int(startPage),
97                                        rt.make_int(endPage));
98     rt.send_callback(onBeginDocument, this, "wxPrintout", args);
99 
100     wxeCommand *cb = ((WxeApp *) wxTheApp)->cb_return;
101     int ret_value;
102     if(cb && enif_get_int(cb->env, cb->args[0], &ret_value)) {
103       delete cb;
104       return ret_value;
105     }
106   }
107   return wxPrintout::OnBeginDocument(startPage,endPage);
108 }
109 
OnEndDocument()110 void EwxPrintout::OnEndDocument()
111 {
112   wxeMemEnv *memenv = (wxeMemEnv *) me_ref->memenv;
113   if(onEndDocument && memenv) {
114     wxeReturn rt = wxeReturn(memenv, memenv->owner, false);
115     ERL_NIF_TERM args = enif_make_list(rt.env, 0);
116     rt.send_callback(onEndDocument, this, "wxPrintOut", args);
117 
118   } else {
119     wxPrintout::OnEndDocument();
120   }
121 }
122 
OnBeginPrinting()123 void EwxPrintout::OnBeginPrinting()
124 {
125   wxeMemEnv *memenv = (wxeMemEnv *) me_ref->memenv;
126   if(onBeginPrinting && memenv) {
127     wxeReturn rt = wxeReturn(memenv, memenv->owner, false);
128     ERL_NIF_TERM args = enif_make_list(rt.env, 0);
129     rt.send_callback(onBeginPrinting, this, "wxPrintout", args);
130   } else {
131     wxPrintout::OnBeginPrinting();
132   }
133 }
134 
OnEndPrinting()135 void EwxPrintout::OnEndPrinting()
136 {
137   wxeMemEnv *memenv = (wxeMemEnv *) me_ref->memenv;
138   if(onEndPrinting && memenv) {
139     wxeReturn rt = wxeReturn(memenv, memenv->owner, false);
140     ERL_NIF_TERM args = enif_make_list(rt.env, 0);
141     rt.send_callback(onEndPrinting, this, "wxPrintout", args);
142   } else {
143     wxPrintout::OnEndPrinting();
144   }
145 }
146 
OnPreparePrinting()147 void EwxPrintout::OnPreparePrinting()
148 {
149   wxeMemEnv *memenv = (wxeMemEnv *) me_ref->memenv;
150   if(onPreparePrinting && memenv) {
151     wxeReturn rt = wxeReturn(memenv, memenv->owner, false);
152     ERL_NIF_TERM args = enif_make_list(rt.env, 0);
153     rt.send_callback(onPreparePrinting, this, "wxPrintout", args);
154   } else {
155     wxPrintout::OnPreparePrinting();
156   }
157 }
158 
HasPage(int page)159 bool EwxPrintout::HasPage(int page)
160 {
161   wxeMemEnv *memenv = (wxeMemEnv *) me_ref->memenv;
162   if(hasPage && memenv) {
163     wxeReturn rt = wxeReturn(memenv, memenv->owner, false);
164     ERL_NIF_TERM args = enif_make_list(rt.env, 1, rt.make_int(page));
165     rt.send_callback(hasPage, this, "wxPrintout", args);
166     wxeCommand *cb = ((WxeApp *) wxTheApp)->cb_return;
167     int ret_value;
168     if(cb && enif_get_int(cb->env, cb->args[0], &ret_value)) {
169       delete cb;
170       return ret_value;
171     }
172   }
173   return wxPrintout::HasPage(page);
174 }
175 
OnPrintPage(int page)176 bool EwxPrintout::OnPrintPage(int page)
177 {
178   wxeMemEnv *memenv = (wxeMemEnv *) me_ref->memenv;
179   if(memenv) {
180     wxeReturn rt = wxeReturn(memenv, memenv->owner, false);
181     ERL_NIF_TERM args = enif_make_list(rt.env, 1, rt.make_int(page));
182     rt.send_callback(onPrintPage, this, "wxPrintout", args);
183     wxeCommand *cb = ((WxeApp *) wxTheApp)->cb_return;
184     int ret_value;
185     if(cb && enif_get_int(cb->env, cb->args[0], &ret_value)) {
186       delete cb;
187       return ret_value;
188     }
189   }
190   return FALSE;
191 }
192 
GetPageInfo(int * minPage,int * maxPage,int * pageFrom,int * pageTo)193 void EwxPrintout::GetPageInfo(int *minPage, int *maxPage, int *pageFrom, int *pageTo)
194 {
195   wxeMemEnv *memenv = (wxeMemEnv *) me_ref->memenv;
196   if(getPageInfo && memenv) {
197     wxeReturn rt = wxeReturn(memenv, memenv->owner, false);
198     ERL_NIF_TERM args = enif_make_list(rt.env, 0);
199     rt.send_callback(getPageInfo, this, "wxPrintout", args);
200     wxeCommand *cb = ((WxeApp *) wxTheApp)->cb_return;
201     if(cb
202        && enif_get_int(cb->env, cb->args[0], minPage)
203        && enif_get_int(cb->env, cb->args[0], maxPage)
204        && enif_get_int(cb->env, cb->args[0], pageFrom)
205        && enif_get_int(cb->env, cb->args[0], pageTo)
206        ) {
207       delete cb;
208     }
209   }
210   wxPrintout::GetPageInfo(minPage, maxPage, pageFrom, pageTo);
211 }
212 
213 /* *****************************************************************/
214 // ListCtrl with callbacks for VIRTUAL_TABLES
215 
OnGetItemText(long item,long col) const216 wxString EwxListCtrl::OnGetItemText(long item, long col) const {
217   wxeMemEnv *memenv = (wxeMemEnv *) me_ref->memenv;
218   if(onGetItemText && memenv) {
219     wxeReturn rt = wxeReturn(memenv, memenv->owner, false);
220     ERL_NIF_TERM args = enif_make_list(rt.env, 2, rt.make_int(item), rt.make_int(col));
221     rt.send_callback(onGetItemText, (wxObject *)this, "wxListCtrl", args);
222 
223     wxeCommand *cb = ((WxeApp *) wxTheApp)->cb_return;
224     ErlNifBinary bin;
225     if(cb && enif_inspect_binary(cb->env, cb->args[0], &bin)) {
226       wxString str = wxString(bin.data, wxConvUTF8, bin.size);
227       delete cb;
228       return str;
229     }
230     return wxT("OnGetItemText must return a string");
231   }
232   return wxT("OnGetItemText not defined");
233 }
234 
OnGetItemAttr(long item) const235 wxListItemAttr* EwxListCtrl::OnGetItemAttr(long item) const {
236   wxeMemEnv *memenv = (wxeMemEnv *) me_ref->memenv;
237   if(onGetItemAttr && memenv) {
238     wxeReturn rt = wxeReturn(memenv, memenv->owner, false);
239     ERL_NIF_TERM args = enif_make_list(rt.env, 1, rt.make_int(item));
240     rt.send_callback(onGetItemAttr, (wxObject *) this, "wxListCtrl",args);
241     wxeCommand *cb = ((WxeApp *) wxTheApp)->cb_return;
242     if(cb) {
243       wxListItemAttr * result = (wxListItemAttr *) memenv->getPtr(cb->env, cb->args[0], "CB item");
244       delete cb;
245       return result;
246     }
247   }
248   return NULL;
249 }
250 
OnGetItemImage(long item) const251 int EwxListCtrl::OnGetItemImage(long item) const {
252   return OnGetItemColumnImage(item, 0);
253 }
254 
OnGetItemColumnImage(long item,long col) const255 int EwxListCtrl::OnGetItemColumnImage(long item, long col) const {
256     wxeMemEnv *memenv = (wxeMemEnv *) me_ref->memenv;
257   if(onGetItemColumnImage && memenv) {
258     wxeReturn rt = wxeReturn(memenv, memenv->owner, false);
259     ERL_NIF_TERM args = enif_make_list(rt.env, 2, rt.make_int(item), rt.make_int(col));
260     rt.send_callback(onGetItemColumnImage, (wxObject *) this, "wxListCtrl",args);
261 
262     wxeCommand *cb = ((WxeApp *) wxTheApp)->cb_return;
263     int ret_value;
264     if(cb && enif_get_int(cb->env, cb->args[0], &ret_value)) {
265       delete cb;
266       return ret_value;
267     }
268   }
269   return -1;
270 }
271 
~EwxListCtrl()272 EwxListCtrl::~EwxListCtrl() {
273   clear_cb(me_ref, onGetItemText);
274   clear_cb(me_ref, onGetItemAttr);
275   clear_cb(me_ref, onGetItemColumnImage);
276   ((WxeApp *)wxTheApp)->clearPtr(this);
277 }
278 
279 /* ****************************************************************************
280  * wxListCtrlCompare wrapper
281  * ****************************************************************************/
282 
wxEListCtrlCompare(wxeIntPtr item1,wxeIntPtr item2,wxeIntPtr callbackInfoPtr)283 int wxCALLBACK wxEListCtrlCompare(wxeIntPtr item1, wxeIntPtr item2, wxeIntPtr callbackInfoPtr)
284 {
285   callbackInfo * cbi = (callbackInfo *)callbackInfoPtr;
286   wxeMemEnv *memenv = (wxeMemEnv *) cbi->me_ref->memenv;
287   if(memenv) {
288     wxeReturn rt = wxeReturn(memenv, memenv->owner, false);
289     ERL_NIF_TERM args = enif_make_list2(rt.env,rt.make_int(item1),rt.make_int(item2));
290     rt.send_callback(cbi->callbackID, args);
291 
292     wxeCommand *cb = ((WxeApp *) wxTheApp)->cb_return;
293     int ret_value;
294     if(cb && enif_get_int(cb->env, cb->args[0], &ret_value)) {
295       delete cb;
296       return ret_value;
297     }
298   }
299   return 0;
300 }
301 
302 
303 /* *****************************************************************/
304 // TaskBarIcon with callbacks for VIRTUAL_TABLES
305 
CreatePopupMenu()306 wxMenu* EwxTaskBarIcon::CreatePopupMenu() {
307   if(createPopupMenu) {
308     wxeMemEnv *memenv = (wxeMemEnv *) me_ref->memenv;
309     if(memenv) {
310       wxeReturn rt = wxeReturn(memenv, memenv->owner, false);
311       ERL_NIF_TERM args = enif_make_list(rt.env, 0);
312       rt.send_callback(createPopupMenu, args);
313 
314       wxeCommand *cb = ((WxeApp *) wxTheApp)->cb_return;
315       wxMenu * ret_value;
316       if(cb && (ret_value = (wxMenu *) memenv->getPtr(cb->env, cb->args[0], "menu"))) {
317         delete cb;
318         return ret_value;
319       }
320     }
321   }
322   return NULL;
323 }
324 
325 
326 // tools
327 
clear_cb(wxe_me_ref * mr,int callback)328 void clear_cb(wxe_me_ref *mr, int callback)
329 {
330   wxeMemEnv *memenv = (wxeMemEnv *) mr->memenv;
331   if(callback > 0 && memenv) {
332     wxeReturn rt = wxeReturn(memenv, memenv->owner, false);
333     ERL_NIF_TERM cb_msg =
334       enif_make_tuple2(rt.env,
335                        rt.make_atom("wx_delete_cb"),
336                        rt.make_int(callback));
337     rt.send(cb_msg);
338   }
339 }
340