aboutsummaryrefslogblamecommitdiffstats
path: root/lib/wx/c_src/wxe_callback_impl.cpp
blob: 3a59004eb02fa728824cf0dbd6e2a22ad850361f (plain) (tree)
1
2
3
4
5
6
7
8
9
10

                   
  
                                                        
  




                                                                      
  



                                                                         

                 




                       

                       

                                 
 




                                                                                



                                                                              
 
                 





                               

 

                                                                                    



                      
                                                









                                                                       










                                                

 


                                                                     











                                                                              
                                                                                 




                                                         
 
                                                                     


                             







                                    






                                                             
                                                              

                         
                                 




                                                        


                                                        

 
                                 

                     
                                                       

                                
   

 
                                   


                       
                                                         

                                  
   

 
                                 


                     
                                                       








                                     
                                                           

                                    
   

 
                                   


               
                                                      
                    
                                 




                                                        


                                   



                                       
                                                        
                  
                               




                                                      

               
 
 


                                                                                     
                                                     
                                        




                                                 

                                                  













                                                                     
                                        

                                                 

                                                  




                                                    
 




                                                             
                                               
                                                                 




                                                                                            














                                                                   




                                                        
     
   







                                       
 




                                                                                
                                                                                              






















                                                                   
        
 
                                                



                                                                 





                               
/*
 * %CopyrightBegin%
 *
 * Copyright Ericsson AB 2008-2014. All Rights Reserved.
 *
 * The contents of this file are subject to the Erlang Public License,
 * Version 1.1, (the "License"); you may not use this file except in
 * compliance with the License. You should have received a copy of the
 * Erlang Public License along with this software. If not, it can be
 * retrieved online at http://www.erlang.org/.
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
 * the License for the specific language governing rights and limitations
 * under the License.
 *
 * %CopyrightEnd%
 */

#include <wx/wx.h>
#include "wxe_impl.h"
#include "wxe_return.h"
#include "wxe_events.h"
#include "wxe_gl.h"
#include "gen/wxe_macros.h"
#include "gen/wxe_derived_dest.h"


/* ****************************************************************************
 * CallbackData *
 * ****************************************************************************/

wxeEvtListener::wxeEvtListener(ErlDrvTermData caller, int req, char *req_type,
			       int funcb, int skip_ev, wxeErlTerm * userData,
			       ErlDrvTermData from_port)
  : wxEvtHandler()
{
  port=from_port;
  listener = caller;
  obj = req;
  fun_id = funcb;
  strcpy(class_name, req_type);
  skip = skip_ev;
  user_data = userData;
}

wxeEvtListener::~wxeEvtListener() {
    // fprintf(stderr, "CBD Deleteing %p %s\r\n", this, class_name); fflush(stderr);
  if(user_data) {
    delete user_data;
  }
  ptrMap::iterator it;
  it = ((WxeApp *)wxTheApp)->ptr2ref.find(this);
  if(it != ((WxeApp *)wxTheApp)->ptr2ref.end()) {
    wxeRefData *refd = it->second;
    wxeReturn rt = wxeReturn(WXE_DRV_PORT, refd->memenv->owner, false);
    rt.addAtom("wx_delete_cb");
    rt.addInt(fun_id);
    rt.addRef(refd->ref, "wxeEvtListener");
    rt.addRef(obj, class_name);
    rt.addTupleCount(4);
    rt.send();
  }
  ((WxeApp *)wxTheApp)->clearPtr(this);
}

void wxeEvtListener::forward(wxEvent& event)
{
#ifdef DEBUG
  if(!sendevent(&event, port))
    fprintf(stderr, "Couldn't send event!\r\n");
#else
sendevent(&event, port);
#endif
}

/* *****************************************************************/
/* Special Class impls */

#define INVOKE_CALLBACK_INIT(port, callback, class_str)		        \
  {									\
    wxeMemEnv * memenv =  ((WxeApp *) wxTheApp)->getMemEnv(port);	\
    wxeReturn rt = wxeReturn(WXE_DRV_PORT, memenv->owner, false);	\
    rt.addInt(callback);						\
    rt.addRef(((WxeApp *) wxTheApp)->getRef((void *)this, memenv), class_str);

#define INVOKE_CALLBACK_END(port, args)					\
  rt.endList(1 + (args));						\
  rt.addAtom("_wx_invoke_cb_");						\
  rt.addTupleCount(3);							\
  rt.send();								\
  handle_event_callback(WXE_DRV_PORT_HANDLE, memenv->owner); 			\
 }

#define INVOKE_CALLBACK(port, callback, class_str)	\
  INVOKE_CALLBACK_INIT(port, callback, class_str);	\
  INVOKE_CALLBACK_END(port, 0)

/* *****************************************************************/
/* Printing special */

wxEPrintout::~wxEPrintout() {
  clear_cb(port, onPrintPage);
  clear_cb(port, onPreparePrinting);
  clear_cb(port, onBeginPrinting);
  clear_cb(port, onEndPrinting);
  clear_cb(port, onBeginDocument);
  clear_cb(port, onEndDocument);
  clear_cb(port, hasPage);
  clear_cb(port, getPageInfo);

  ((WxeApp *)wxTheApp)->clearPtr(this);
}

bool wxEPrintout::OnBeginDocument(int startPage, int endPage)
{
  if(onBeginDocument) {
    INVOKE_CALLBACK_INIT(port, onBeginDocument, "wxPrintout");
    rt.addInt(startPage);
    rt.addInt(endPage);
    INVOKE_CALLBACK_END(port, 2);
    if(((WxeApp *) wxTheApp)->cb_buff) {
      int res = * (int*) ((WxeApp *) wxTheApp)->cb_buff;
      driver_free(((WxeApp *) wxTheApp)->cb_buff);
      ((WxeApp *) wxTheApp)->cb_buff = NULL;
      return res;
    }
  }
  return wxPrintout::OnBeginDocument(startPage,endPage);
}

void wxEPrintout::OnEndDocument()
{
  if(onEndDocument) {
    INVOKE_CALLBACK(port, onEndDocument, "wxPrintout");
  } else {
    wxPrintout::OnEndDocument();
  }
}

void wxEPrintout::OnBeginPrinting()
{

  if(onBeginPrinting) {
    INVOKE_CALLBACK(port, onBeginPrinting, "wxPrintout");
  } else {
    wxPrintout::OnBeginPrinting();
  }
}

void wxEPrintout::OnEndPrinting()
{

  if(onEndPrinting) {
    INVOKE_CALLBACK(port, onEndPrinting, "wxPrintout");
  } else {
    wxPrintout::OnEndPrinting();
  }
}

void wxEPrintout::OnPreparePrinting()
{

  if(onPreparePrinting) {
    INVOKE_CALLBACK(port, onPreparePrinting, "wxPrintout");
  } else {
    wxPrintout::OnPreparePrinting();
  }
}

bool wxEPrintout::HasPage(int page)
{

  if(hasPage) {
    INVOKE_CALLBACK_INIT(port, hasPage, "wxPrintout");
    rt.addInt(page);
    INVOKE_CALLBACK_END(port, 1);
    if(((WxeApp *) wxTheApp)->cb_buff) {
      int res = * (int*) ((WxeApp *) wxTheApp)->cb_buff;
      driver_free(((WxeApp *) wxTheApp)->cb_buff);
      ((WxeApp *) wxTheApp)->cb_buff = NULL;
      return res;
    }
  }
  return wxPrintout::HasPage(page);
}

bool wxEPrintout::OnPrintPage(int page)
{
  INVOKE_CALLBACK_INIT(port, onPrintPage, "wxPrintout");
  rt.addInt(page);
  INVOKE_CALLBACK_END(port, 1);
  if(((WxeApp *) wxTheApp)->cb_buff) {
    int res = * (int*) ((WxeApp *) wxTheApp)->cb_buff;
    driver_free(((WxeApp *) wxTheApp)->cb_buff);
    ((WxeApp *) wxTheApp)->cb_buff = NULL;
    return res;
  }
  return FALSE;
}

void wxEPrintout::GetPageInfo(int *minPage, int *maxPage, int *pageFrom, int *pageTo)
{
  if(getPageInfo) {
    INVOKE_CALLBACK(port, getPageInfo, "wxPrintout");
    if(((WxeApp *) wxTheApp)->cb_buff) {
      char * bp = ((WxeApp *) wxTheApp)->cb_buff;
      *minPage  = *(int *) bp; bp += 4;
      *maxPage  = *(int *) bp; bp += 4;
      *pageFrom = *(int *) bp; bp += 4;
      *pageTo   = *(int *) bp; bp += 4;
      driver_free(((WxeApp *) wxTheApp)->cb_buff);
      ((WxeApp *) wxTheApp)->cb_buff = NULL;
    }
  }
  wxPrintout::GetPageInfo(minPage, maxPage, pageFrom, pageTo);
}

/* *****************************************************************/
// ListCtrl with callbacks for VIRTUAL_TABLES

wxString EwxListCtrl::OnGetItemText(long item, long col) const {
  if(onGetItemText) {
    INVOKE_CALLBACK_INIT(port, onGetItemText, "wxListCtrl");
    rt.addInt(item);
    rt.addInt(col);
    INVOKE_CALLBACK_END(port, 2);
    if(((WxeApp *) wxTheApp)->cb_buff) {
      char * bp = ((WxeApp *) wxTheApp)->cb_buff;
      wxString str = wxString(bp, wxConvUTF8);
      driver_free(((WxeApp *) wxTheApp)->cb_buff);
      ((WxeApp *) wxTheApp)->cb_buff = NULL;
      return str;
    }
  }
  return wxT("OnGetItemText not correctly defined");
}

wxListItemAttr* EwxListCtrl::OnGetItemAttr(long item) const {
  if(onGetItemAttr) {
    INVOKE_CALLBACK_INIT(port, onGetItemAttr, "wxListCtrl");
    rt.addInt(item);
    INVOKE_CALLBACK_END(port, 1);
    char * bp = ((WxeApp *) wxTheApp)->cb_buff;
    wxeMemEnv * memenv =  ((WxeApp *) wxTheApp)->getMemEnv(port);
    if(bp) {
      wxListItemAttr * result = (wxListItemAttr *)((WxeApp *) wxTheApp)->getPtr(bp, memenv);
      driver_free(((WxeApp *) wxTheApp)->cb_buff);
      ((WxeApp *) wxTheApp)->cb_buff = NULL;
      return result;
    }
  }
  return NULL;
}

int EwxListCtrl::OnGetItemImage(long item) const {
  return OnGetItemColumnImage(item, 0);
}

int EwxListCtrl::OnGetItemColumnImage(long item, long col) const {
  if(onGetItemColumnImage) {
    INVOKE_CALLBACK_INIT(port, onGetItemColumnImage, "wxListCtrl");
    rt.addInt(item);
    rt.addInt(col);
    INVOKE_CALLBACK_END(port, 2);
    if(((WxeApp *) wxTheApp)->cb_buff) {
      int res = * (int*) ((WxeApp *) wxTheApp)->cb_buff;
      driver_free(((WxeApp *) wxTheApp)->cb_buff);
      ((WxeApp *) wxTheApp)->cb_buff = NULL;
      return res;
    }
  }
  return -1;
}

EwxListCtrl::~EwxListCtrl() {
  clear_cb(port, onGetItemText);
  clear_cb(port, onGetItemAttr);
  clear_cb(port, onGetItemColumnImage);
  ((WxeApp *)wxTheApp)->clearPtr(this);
}

/* ****************************************************************************
 * wxListCtrlCompare wrapper
 * ****************************************************************************/

int wxCALLBACK wxEListCtrlCompare(wxeIntPtr item1, wxeIntPtr item2, wxeIntPtr callbackInfoPtr)
{
  callbackInfo * cb = (callbackInfo *)callbackInfoPtr;
  wxeMemEnv * memenv =  ((WxeApp *) wxTheApp)->getMemEnv(cb->port);
  wxeReturn rt = wxeReturn(WXE_DRV_PORT, memenv->owner, false);
  rt.addInt(cb->callbackID);
  rt.addInt(item1);
  rt.addInt(item2);
  rt.endList(2);
  rt.addAtom("_wx_invoke_cb_");
  rt.addTupleCount(3);
  rt.send();
  handle_event_callback(WXE_DRV_PORT_HANDLE, memenv->owner);

  if(((WxeApp *) wxTheApp)->cb_buff) {
    int res = * (int*) ((WxeApp *) wxTheApp)->cb_buff;
    driver_free(((WxeApp *) wxTheApp)->cb_buff);
    ((WxeApp *) wxTheApp)->cb_buff = NULL;
    return res;
  }
  return 0;
}


// tools

void clear_cb(ErlDrvTermData port, int callback)
{
  if(callback > 0) {
    wxeMemEnv * memenv =  ((WxeApp *) wxTheApp)->getMemEnv(port);
    wxeReturn rt = wxeReturn(WXE_DRV_PORT, memenv->owner, false);
    rt.addAtom("wx_delete_cb");
    rt.addInt(callback);
    rt.addTupleCount(2);
    rt.send();
  }
}