aboutsummaryrefslogtreecommitdiffstats
path: root/lib/wx/c_src/wxe_gl.cpp
blob: eb4462047f615428e43d99b4f410a5d25918f9ad (plain) (blame)
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
/*
 * %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>
#include <dlfcn.h>
#include "wxe_impl.h"
#include "wxe_return.h"

#define WX_DEF_EXTS

/* **************************************************************************** 
 * Opengl context management *
 * ****************************************************************************/

int erl_gl_initiated = FALSE;
ErlDrvTermData gl_active = 0;
wxeGLC glc;

typedef void (*WXE_GL_DISPATCH) (int, char *, ErlDrvPort, ErlDrvTermData, char **);
WXE_GL_DISPATCH wxe_gl_dispatch;

#ifdef _WIN32
void * dlsym(HMODULE Lib, const char *func) {
  funcp = (void *) GetProcAddress(Lib, func);
  return funcp;
}
#endif 

void wxe_initOpenGL(wxeReturn rt, char *bp) {
  void * LIBhandle;
  int (*init_opengl) ();

  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)();
	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 {
    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 *) "_wxe_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];
  for(int i=0; i<3; i++) {
    if(bins[i]) 
      bs[i] = bins[i]->base;
    else 
      bs[i] = NULL;
  }
  wxe_gl_dispatch(op, bp, WXE_DRV_PORT, caller, bs);
}