/* * %CopyrightBegin% * * Copyright Ericsson AB 2008-2010. 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 <stdio.h> #include <string.h> #ifndef _WIN32 #include <dlfcn.h> #else #include <windows.h> #endif #include "wxe_impl.h" #include "wxe_return.h" /* **************************************************************************** * Opengl context management * * ****************************************************************************/ int erl_gl_initiated = FALSE; ErlDrvTermData gl_active = 0; wxeGLC glc; typedef void (*WXE_GL_DISPATCH) (int, char *, ErlDrvPort, ErlDrvTermData, char **, int *); WXE_GL_DISPATCH wxe_gl_dispatch; #ifdef _WIN32 #define RTLD_LAZY 0 typedef HMODULE DL_LIB_P; void * dlsym(HMODULE Lib, const char *func) { void * funcp; if((funcp = (void *) GetProcAddress(Lib, func))) return funcp; else return (void *) wglGetProcAddress(func); } HMODULE dlopen(const char *path, int unused) { WCHAR * DLL; int len = MultiByteToWideChar(CP_ACP, 0, path, -1, NULL, 0); DLL = (WCHAR *) malloc(len * sizeof(WCHAR)); MultiByteToWideChar(CP_ACP, 0, path, -1, DLL, len); HMODULE lib = LoadLibrary(DLL); free(DLL); return lib; } void dlclose(HMODULE Lib) { FreeLibrary(Lib); } #else typedef void * DL_LIB_P; #endif void wxe_initOpenGL(wxeReturn rt, char *bp) { DL_LIB_P LIBhandle; int (*init_opengl)(void *); #ifdef _WIN32 void * erlCallbacks = &WinDynDriverCallbacks; #else void * erlCallbacks = NULL; #endif if(erl_gl_initiated == FALSE) { if((LIBhandle = dlopen(bp, RTLD_LAZY))) { *(void **) (&init_opengl) = dlsym(LIBhandle, "egl_init_opengl"); wxe_gl_dispatch = (WXE_GL_DISPATCH) dlsym(LIBhandle, "egl_dispatch"); if(init_opengl && wxe_gl_dispatch) { (*init_opengl)(erlCallbacks); rt.addAtom((char *) "ok"); rt.add(wxString::FromAscii("initiated")); rt.addTupleCount(2); erl_gl_initiated = TRUE; } else { wxString msg; msg.Printf(wxT("In library: ")); msg += wxString::FromAscii(bp); msg += wxT(" functions: "); if(!init_opengl) msg += wxT("egl_init_opengl "); if(!wxe_gl_dispatch) msg += wxT("egl_dispatch "); rt.addAtom((char *) "error"); rt.add(msg); rt.addTupleCount(2); } } else { wxString msg; msg.Printf(wxT("Could not load dll: ")); msg += wxString::FromAscii(bp); rt.addAtom((char *) "error"); rt.add(msg); rt.addTupleCount(2); } } else { rt.addAtom((char *) "ok"); rt.add(wxString::FromAscii("already initilized")); rt.addTupleCount(2); } rt.send(); } void setActiveGL(ErlDrvTermData caller, wxGLCanvas *canvas) { gl_active = caller; glc[caller] = canvas; } void deleteActiveGL(wxGLCanvas *canvas) { gl_active = 0; wxeGLC::iterator it; for(it = glc.begin(); it != glc.end(); ++it) { if(it->second == canvas) { it->second = (wxGLCanvas *) 0; } } } void gl_dispatch(int op, char *bp,ErlDrvTermData caller,WXEBinRef *bins[]){ if(caller != gl_active) { wxGLCanvas * current = glc[caller]; if(current) { gl_active = caller; current->SetCurrent();} else { ErlDrvTermData rt[] = // Error msg {ERL_DRV_ATOM, driver_mk_atom((char *) "_egl_error_"), ERL_DRV_INT, op, ERL_DRV_ATOM, driver_mk_atom((char *) "no_gl_context"), ERL_DRV_TUPLE,3}; driver_send_term(WXE_DRV_PORT,caller,rt,8); return ; } }; char * bs[3]; int bs_sz[3]; for(int i=0; i<3; i++) { if(bins[i]) { bs[i] = bins[i]->base; bs_sz[i] = bins[i]->size; } else bs[i] = NULL; } wxe_gl_dispatch(op, bp, WXE_DRV_PORT, caller, bs, bs_sz); }